问题:
之前使用下面的代码从 NetworkStream 中读取数据,后来发现当服务器重启(tcp 连接断开)后,继续使用服务器重启前建立的 socket 连接(使用了 socket 连接池)从 NetworkStream 读取数据,并没有抛异常,而是 await ReadAsync 的返回值一直是 0 , 也就是下面的 currentRead 值一直为 0 ,结果造成死循环。
public async Task ReadAsync(byte[] buffer, int offset, int count)
{
int read = 0;
int shouldRead = count;
while (read < count)
{
int currentRead = await _inputStream.ReadAsync(buffer, offset, shouldRead);
if (currentRead < 1)
continue;
read += currentRead;
offset += currentRead;
shouldRead -= currentRead;
}
}
为了解决这个问题,今天将上面代码中的 continue
改为了 break
,但这样改是否会带来漏读数据的问题?有没有可能出现这样的情况:currentRead 为 0 时,下一个循环中还能读到数据?
NetworkStream.ReadAsync 方法帮助文档是这么写的:
// Returns:
// A task that represents the asynchronous read operation. The value of the TResult
// parameter contains the total number of bytes read into the buffer. The result
// value can be less than the number of bytes requested if the number of bytes currently
// available is less than the requested number, or it can be 0 (zero) if the end
// of the stream has been reached.
"the end of the stream has been reached.",是不是就是表示这次网络数据传输已经结束?
回答1:
currentRead 为 0 说明 当前 Stream 已经没有其他数据了。
Read returns 0 only when there is no more data in the stream and no more is expected (such as a closed socket or end of file)
When does Network Stream Read returns 0?
回答2:
返回0,只是表示当前没有数据可以读取。不代表当前连接已经嗝屁了。
如果连接已经断开了,socket肯定是回throw 异常出来的,这是tcp协议决定了的,在查查是哪里出问题了,比如是不是有proxy之类的。