Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/selenium/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 异步套接字不返回完整页面_C#_Sockets_Asynchronous - Fatal编程技术网

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调用中读取的字节数时进行一些诊断。