tunafish24
tunafish24

Reputation: 2469

Tcpclient stream.ReadAsync does not return 0 when socket/stream closes?

I'm using TcpClient.Stream.ReadAsync to receive data in a loop. Traditionally, windows sockets return 0 when the socket closes gracefully. With the following code, the only time ReadAsync returns is when there is actual data. If I close the remote app (gracefully or forcefully) or even if I call Stream.Close() on the TcpClient, the ReadAsync still doesn't complete or throw an exception. How do I get ReadAsync to complete?

var amountRead = await stream.ReadAsync(conn.buffer, 0, Connection.BufferSize, ct);

if (amountRead == 0)
    break; //end of stream.
else
{
    //Process Received Data here
}

Upvotes: 2

Views: 2774

Answers (1)

Stephen Cleary
Stephen Cleary

Reputation: 456507

No, the ReadAsync reading semantics are exactly the same as BeginRead and Read. The read will return a 0-byte result at the end of the stream.

It's possible that the remote server is not closing the socket gracefully. Public-facing servers often do this to avoid the 4-way closing handshake. Unfortunately, this means that you as the client need to detect when the socket is closed. Traditionally, this is done by using a keepalive message or packet. I have a blog post with more details; but the key is it has to be an active detection - i.e., the client has to send something to detect the connection is no longer there.

On a side note, I'm not sure what closing the stream would do. But I'm fairly certain that closing the socket (TcpClient) would cause the stream read to complete with an error.

Upvotes: 2

Related Questions