您好我已经尝试向Shoutcast流网站发送和http请求,然后阅读响应, 我有两个来源,一个是主要的(我用wpf测试过),其他的有点 套接字的帮手...好吧所有的工作,与localhost和其他网站 但是当我尝试向“209.9.238.6:6042”发送请求时,响应中的标题永远不会 完成但是中继。
我已经做了很多测试,但它只适用于Thread.sleep(200); 发送和接收之间看(1),所以看来listen()来得太早了 只下载了一部分......
你能帮助我吗?main.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void connectionButton_Click(object sender, RoutedEventArgs e)
{
var url = "209.9.238.6:6042";
var sockHelp = new SocketHelper(url);
sockHelp.onConnect += sockHelp_onConnect;
sockHelp.connect();
}
void testDebug(string str) {
Action action = () => debugTxt.Text = str;
Dispatcher.BeginInvoke(action);
}
void sockHelp_onConnect(object sender, SocketHelperEventArgs e)
{
var sockHelp = sender as SocketHelper;
testDebug("Connected");
var header = "";
header+="GET / HTTP/1.0\r\n";
header+="Accept: */*\r\n";
header+="Host: 209.9.238.6\r\n";
header+="Connection: close\r\n\r\n";
sockHelp.onSend += sockHelp_onSend;
sockHelp.sendAsync(Encoding.UTF8.GetBytes(header));
}
private void sockHelp_onSend(object sender, SocketAsyncEventArgs e)
{
var sockHelp = sender as SocketHelper;
sockHelp.onReceive+=sockHelp_onReceive;
//Thread.Sleep(200); (1) uncomment this line... to make works
sockHelp.listen();
}
void sockHelp_onReceive(object sender, SocketAsyncEventArgs arg_)
{
testDebug("Receiving");
var t = Encoding.UTF8.GetString(arg_.Buffer);
var idx = IndexOf(arg_.Buffer, new byte[] { 0x0d, 0x0a, 0x0d, 0x0a });
if (idx < 0)
{
testDebug(Encoding.UTF8.GetString(arg_.Buffer));
return ;
}
byte[] binBuff = new byte[idx + 1];
System.Buffer.BlockCopy(arg_.Buffer, 0, binBuff, 0, idx + 1);
testDebug(Encoding.UTF8.GetString(binBuff));
}
private int IndexOf(byte[] searchIn, byte[] searchFor)
{
if ((searchIn != null) && (searchIn != null))
{
if (searchFor.Length > searchIn.Length) return 0;
for (int i = 0; i < searchIn.Length; i++)
{
int startIndex = i;
bool match = true;
for (int j = 0; j < searchFor.Length; j++)
{
if (searchIn[startIndex] != searchFor[j])
{
match = false;
break;
}
else if (startIndex < searchIn.Length)
{
startIndex++;
}
}
if (match)
return startIndex - searchFor.Length;
}
}
return -1;
}
}
}
helper.cs
namespace TestSocket
{
/// <summary>
/// </summary>
public class SocketHelperEventArgs : EventArgs
{
public SocketHelperEventArgs(SocketError se)
{
socketError = se;
}
public SocketHelperEventArgs() { }
SocketError socketError;
SocketAsyncEventArgs args;
}
public class SocketHelper
{
byte[] _buffer = new byte[1024*2];
SocketAsyncEventArgs _args = new SocketAsyncEventArgs();
readonly Socket _socket;
public event EventHandler<SocketHelperEventArgs> onError;
public event EventHandler<SocketHelperEventArgs> onConnect;
public event EventHandler<SocketAsyncEventArgs> onReceive;
public event EventHandler<SocketAsyncEventArgs> onSend;
public SocketHelper(string url)
{
int port=0;
string[] addressVector = url.Split(':');
if (addressVector.Length == 1)
port = 80;
else
port = int.Parse(addressVector[1]);
_args.RemoteEndPoint = new DnsEndPoint(addressVector[0], port); ;
_args.Completed += SocketAsyncEventArgs_Completed;
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
}
public void listen()
{
_args.SetBuffer(_buffer, 0, _buffer.Length);
_socket.ReceiveAsync(_args);
}
public void connect()
{
bool completesAsynchronously = _socket.ConnectAsync(_args);
if (!completesAsynchronously)
{
SocketAsyncEventArgs_Completed(_args.ConnectSocket, _args);
}
}
public void sendAsync(byte[] data) {
_args.SetBuffer(data, 0, data.Length);
_socket.SendAsync(_args);
}
private void SocketAsyncEventArgs_Completed(object sender, SocketAsyncEventArgs e)
{
// check for errors
if (e.SocketError != SocketError.Success)
{
if (onError != null) onError(this, new SocketHelperEventArgs(e.SocketError));
CleanUp(e);
return;
}
switch (e.LastOperation)
{
case SocketAsyncOperation.Connect:
if (onConnect != null) onConnect(this, EventArgs.Empty as SocketHelperEventArgs);
break;
case SocketAsyncOperation.Send:
if (onSend!= null) onSend(this, e);
break;
case SocketAsyncOperation.Receive:
if (onReceive != null) onReceive(this,e);
break;
}
}
private void CleanUp(SocketAsyncEventArgs e)
{
if (e.ConnectSocket != null)
{
e.ConnectSocket.Shutdown(SocketShutdown.Both);
e.ConnectSocket.Close();
}
}
}
}
答案 0 :(得分:2)
您似乎假设您将在一次阅读中获得整个回复。那不对。当数据可用时,您将从套接字获得一些数据。您需要根据应用程序级协议(HTTP或ICY或您正在使用的任何内容)检测是否有更多数据,如果是,请重新设置异步读取。
现在你正在消耗套接字接收缓冲区中发生的任何事情。等待似乎只是因为在超时后更多的数据堆积在那里,但是不能保证你得到了所有东西。