2015-12-31 161 views
0

目前我一直在努力,从使用TcpClient的服务器接收数据的程序。我的问题是,无论什么时候我读取流,直到我的客户停止工作,它只是冻结。我想保持与服务器的连续连接,但是在我的while函数运行两次之后,第三个循环不会执行读取操作,也不会返回任何内容。避免的NetworkStream读取块

As this answer states that I'm correct

我怎样才能打破或返回这个while循环,或以某种方式绕过读取块?

using (NetworkStream stream = client.GetStream()) 
{ 
    byte[] data = new byte[2048]; 
    using (MemoryStream ms = new MemoryStream()) 
    { 

     int numBytesRead; 
     while ((numBytesRead = stream.Read(data, 0, data.Length)) > 0) 
     { 
      ms.Write(data, 0, numBytesRead); 
     } 
     return ms.ToArray(); 
    } 
} 
+0

我无法从你的代码,并说明是否真的用'Read'呼叫的问题告诉我们,但承担的时刻,它只是需要一些时间来获得下一批数据,只有这样才能让你的在如此长时间的阅读中GUI响应是通过在单独的线程上进行联网。 – adv12

+0

实际上,我将限定我的上述评论:您也可以使用'BeginRead' /'EndRead'。 – adv12

+0

我真的没测试,服务器会发送长度1654字节,然后同时读取它两次:1460和194,然后是1654年但当第三循环运行,如果数据是0它会检查中,循环只是在那里搜索,并且不再启动,只是等待更多的数据。 – DreTaX

回答

-1

我会尽我所能为您提供一些提示。如果你不想在UI被冻结呢,你要么把一个单独的线程这段代码,或运行它作为异步任务,作为沃特评论。在我看来,如果你既不知道你期望接收多少字节,也不知道他们什么时候接触到你,这将是更好的方法。正如你所说,如果你想让这项任务长时间运行,那么线程就是一个很好的解决方案。然而,如果可能的话,你应该关心两件事情:你的TcpClient ReadTimeout属性和你通过第三个参数stream.Read()传递的预期长度。这意味着您将被阻止X毫秒,直到您收到您想要的数量。我在事务服务器上工作过很多,在这些网络之间传输的数据包以前缀的长度为前缀。如果这是你的情况,我建议先读取前缀,然后计算剩余的字节数来读取,然后执行上一次读取操作。

希望这会有所帮助,这是我的第一个答案。

+0

的问题是,所读取的stucks上,而我已经收到数据。我会尝试检查readtimeout。 – DreTaX

+0

如果您遇到Read()调用,您如何确保您已收到数据?对不起,我乍一看不明白你的问题。 –

+0

“我确实测试过它,服务器发送一个长度为1654的字节,然后读取它两次:1460,然后是194,这是1654。但是,当第三个循环运行时,它会检查数据是否为0,循环只是在那里搜索,而不再启动,只是等待更多的数据“服务器说,长度也是1654 – DreTaX