开发者

C# Async sockets dont return the full page

开发者 https://www.devze.com 2023-03-25 19:07 出处:网络
This is my create socket part: _client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

This is my create socket part:

_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");

The recv part:

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();
        }

    }

The Buffer

    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();
    }

Why is this code not returning the full page?

Is there something wrong with this part in recvcallback

if (bytesRead > 0)


You appear to be assuming that you will only be called back when either the buffer is full or the connection has been closed. That's simply not the case. You could have an 8K buffer, and 20K of data being sent from the server, which is read as 2K in each of 10 calls.

Assuming you want to read until the connection is closed, you should keep going until client.EndReceive returns 0. (For HTTP with keepalive, you'd need to read the content length and keep going until you'd read that much data in the body.)

EDIT: I've just seen you've set Keep-Alive on the connection. Don't do that if you want the server to close the connection to tell you it's finished!

(In general, it's much better to use an HTTP library for all of this, of course - why are you writing your own HTTP-handling code?)


Check your buffer length. Probably is much shorter than the effective page length. So, you must accumulate the chunks received on another buffer, then retrigger the BeginReceive until the data length is zero.

0

精彩评论

暂无评论...
验证码 换一张
取 消