9

I discovered that the following code loops with 100% CPU usage:

byte[] buffer = new byte[0x10000];
while (true) {
    if (socket.Poll (5000000, SelectMode.SelectRead) == false)
        continue;
    int available = socket.Available;
    if (available == 0)
        return;
    int read = socket.Receive (buffer);
    Console.WriteLine ("Read: " + read + " Available: " + available);
    /* ... */
}

The output is:

Read: 0 Available: 1
Read: 0 Available: 1
Read: 0 Available: 1
Read: 0 Available: 1
Read: 0 Available: 1
...

I was expecting the socket.Receive method to read that remaining byte but it apparently doesn't resulting in my code looping at 100%.

As suggested by jgauffin the documentation reads:

If the remote host shuts down the Socket connection with the Shutdown method, and all available data has been received, the Receive method will complete immediately and return zero bytes.

So reading 0 is kind of expected but only after all data is read, which socket.Available claims is not.

Documentation for Socket.Available only mention a closed connection throwing an exception.

How could I make sure that last byte is read?

Related: this is an answer of how to detect a closed connection that is dependent on the socket.Available being 0 when there is no more data and the connection is closed,

Community
  • 1
  • 1
hultqvist
  • 17,451
  • 15
  • 64
  • 101
  • I think that it's a bug that Available returns 0 when the connection have been closed. Someone from MS might find your question and give a proper answer. What you can do is to try to send something and see the number of bytes that the Send method returns. If it returns 0, the connection is really closed. – jgauffin May 03 '11 at 18:53

1 Answers1

12

Have you read the documentation?

0 bytes read means that the remote end point have disconnected.

Either use blocking sockets or use the asynchronous methods like BeginReceive(). There is no need for Poll in .Net.

jgauffin
  • 99,844
  • 45
  • 235
  • 372
  • I found that part of the documentation a bit vague stating that disconnection -> read 0, not necessarily the other way around. How about the Available > 0, how should I interpret that? – hultqvist May 03 '11 at 11:52
  • 2
    It was a long time ago I read the doc. I can agree that is wasn't really clear. You should ***always*** treat `0` as return value from `Receive()` as disconnection, no matter what other methods/properties say. Quote from MSDN: `If you are in non-blocking mode, and there is no data available in the in the protocol stack buffer, the Receive method will complete immediately and throw a SocketException`. I do strongly recommend that you stop using non-blocking sockets in .NET. – jgauffin May 03 '11 at 12:03
  • You have a detailled explication here : http://stackoverflow.com/a/1388691/1529139 – 56ka Oct 29 '13 at 12:43
  • @zahirdhada: you can now. – jgauffin Mar 13 '15 at 08:39