C# 异步套接字不返回完整页面
这是我的创建套接字部件:C# 异步套接字不返回完整页面,c#,sockets,asynchronous,C#,Sockets,Asynchronous,这是我的创建套接字部件: _client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); _client.BeginConnect(_IPEnd, new AsyncCallback(ConnectCallback), _client); connectDone.WaitOne(); Send(_client, "GET / HTTP/1.1\r\nHost: www.google.de
_client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_client.BeginConnect(_IPEnd, new AsyncCallback(ConnectCallback), _client);
connectDone.WaitOne();
Send(_client, "GET / HTTP/1.1\r\nHost: www.google.de\r\nConnection: Keep-Alive\r\n\r\n");
recv部分:
private void Receive()
{
// Create the state object.
StateObject state = new StateObject();
state.workSocket = _client;
// Begin receiving the data from the remote device.
_client.BeginReceive(state.buffer, 0, state.buffer.Length , 0, new AsyncCallback(ReceiveCallback), state);
}
private void ReceiveCallback(IAsyncResult ar)
{
// Retrieve the state object and the client socket
// from the asynchronous state object.
StateObject state = (StateObject)ar.AsyncState;
Socket client = state.workSocket;
// Read data from the remote device.
int bytesRead = client.EndReceive(ar);
if (bytesRead > 0)
{
// There might be more data, so store the data received so far.
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
client.BeginReceive(state.buffer,0,state.buffer.Length, 0, new AsyncCallback(ReceiveCallback), state);
}
else
{
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
int length = state.sb.ToString().Length;
ProcessData(state.sb.ToString());
receiveDone.Set();
}
}
缓冲区
public class StateObject
{
private Guid ID = Guid.NewGuid();
// Client socket.
public Socket workSocket = null;
// Size of receive buffer.
public const int BufferSize = 4096;
// Receive buffer.
public byte[] buffer = new byte[BufferSize];
public StringBuilder sb = new StringBuilder();
}
为什么这段代码不返回整页
recvcallback中的此部分有问题吗
if (bytesRead > 0)
您似乎认为只有在缓冲区已满或连接已关闭时才会被回调。事实并非如此。您可以有一个8K缓冲区,从服务器发送20K数据,在10次调用中每次读取2K
假设您想一直读到连接关闭,那么您应该一直读到client.EndReceive
返回0为止。(对于使用keepalive的HTTP,您需要读取内容长度并继续执行,直到读取了正文中的大量数据。)
编辑:我刚刚看到你在连接上设置了Keep Alive。如果您希望服务器关闭连接并告诉您连接已完成,请不要这样做
(一般来说,使用HTTP库来完成所有这些都要好得多,当然-为什么要编写自己的HTTP处理代码?检查缓冲区长度。可能比有效页面长度短得多。因此,您必须累积在另一个缓冲区上接收的数据块,然后重新触发BeginReceive,直到数据长度为零。因此,当页面为20k字节时,我是否必须将缓冲区设置为20000大小?不,这将是解决问题的一个糟糕方法。例如,块缓冲区应该是4096字节。然后,当一个块已满或整个流结束时,套接字将回叫您。每个接收到的块都必须附加到另一个(我可以说)流中,这就是结果文件。然而,正如Jon所观察到的,在下载块的过程中,你必须保持连接打开。@jeb:这当然更好-但是如果你没有收到任何数据,你显然不需要
Append
调用……您好,我的代码只有在我一步一步地通过代码时才起作用,然后它返回28000长度,但是如果我正常运行,它的长度只有4000,你知道为什么吗?@jeb:是的,当你正常运行时,你读取数据的速度和数据到达的速度一样快。当您单步通过时,由于涉及到手动步骤,在您接到接听电话时,所有信息都已到达。我如何解决这一问题?那么异步代码可以工作了?怎么了?我已经试了一整天了,如果你能告诉我,那就太好了me@jeb:啊,那么正常运行时总共只返回4000个字符?在显示每个EndReceive调用中读取的字节数时进行一些诊断。