Alexander.It
Alexander.It

Reputation: 187

When Socket.EndRead() returns 0?

In MSDN example of async client the EndRead is called in this way:

private static void ReceiveCallback( IAsyncResult ar ) {
        try {
            // 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));

                // Get the rest of the data.
                client.BeginReceive(state.buffer,0,StateObject.BufferSize,0,
                    new AsyncCallback(ReceiveCallback), state);
            } else {
                // All the data has arrived; put it in response.
                if (state.sb.Length > 1) {
                    response = state.sb.ToString();
                }
                // Signal that all bytes have been received.
                receiveDone.Set();
            }
        } catch (Exception e) {
            Console.WriteLine(e.ToString());
        }
}

BUT how can bytesRead be zero? according to the documentation EndReceive is blocked till the connection is closed. Is <EOF> a valid buffer terminator for Socket.BeginReceive? The connection seems to be closed only because of client is "Shutdowned". Is it correct?

Upvotes: 0

Views: 1092

Answers (1)

Peter Duniho
Peter Duniho

Reputation: 70652

This is how streams in general, and TCP sockets in particular, all work. You keep reading from them until a read operation completes but with a returned byte count of 0. The 0 is the signal to your code that there is no more data to be read.

In the case of a TCP socket's stream (e.g. one returned from TcpClient.GetStream()), the protocol knows that no more data will be available to be read when the remote end performs a shutdown operation using "send" or "both" as the parameter. This is how the remote end actually signals it's done sending data.

At the local end, this is interpreted as the end of the stream. Which in turn is reported to your code by, as I said above, by the completion of a read operation where the number of bytes read is 0.

Upvotes: 1

Related Questions