当有数据返回时,以下工作正常。但是,对于返回空流是有效的,此时下面会挂起stream.read()。如何重构它以满足两种情况?
using(TcpClient client = new TcpClient(_server, _port))
using(NetworkStream stream = client.GetStream())
{
stream.Write(data, 0, data.Length);
byte[] myReadBuffer = new byte[1024];
int numberOfBytesRead = 0;
var message = new List<Byte> ();
do{
numberOfBytesRead = stream.Read(myReadBuffer, numberOfBytesRead, myReadBuffer.Length);
message.AddRange(myReadBuffer.Take(numberOfBytesRead));
}
while(stream.DataAvailable);
return message.ToArray();
}
答案 0 :(得分:1)
如果我正确理解了代码示例,那么您真正要做的就是从套接字读取所有字节(即TCP连接),然后将它们作为byte[]
返回。如果是这样的话,那就更好了:
using(TcpClient client = new TcpClient(_server, _port))
using(NetworkStream stream = client.GetStream())
using(MemoryStream output = new MemoryStream())
{
stream.CopyTo(output);
return output.ToArray();
}
作为一般规则,我强烈建议不要使用DataAvailable
属性。在这种情况下,它特别不合适,因为它所做的只是检查可以从流中读取多少字节,如果它不为零,则返回true
。空流将永远不会有字节可用,并且就此而言,即使流不为空,也永远不会检测到流的结束(即,无法判断另一端何时完成向您发送数据)。
如果我误解了你真的只想返回立即可用的字节,那么我就无法在没有更多上下文的情况下提供答案。 正确实现这一目的的方法是使用异步I / O,其中一个层可以理解流的整体结构(即数据边界所在的位置),但是实现它的细节是'如果您的问题存在,那么就不可能提供具体的建议。
答案 1 :(得分:1)
您永远无法判断是否会有更多数据或流是否耗尽。远程端必须向您发出流的结束信号。
通过关闭或关闭套接字,您将读取0
字节,这是您停止阅读的信号。
或者,让远程端发送数据信号通知流的末尾。
您使用DataAvailable
是一个错误(99%的此类用法都是错误)。 DataAvailable
是毒药。它告诉您现在可以以非阻塞方式读取多少数据。 1us之后,答案可能会有所不同。
你需要扔掉它。