【问题标题】:Copying NetworkStream to MemoryStream takes infitity ∞ days将 NetworkStream 复制到 MemoryStream 需要无穷 ∞ 天
【发布时间】:2012-07-31 21:45:33
【问题描述】:

我有以下代码:

_clientRequestStream = _tcpClient.GetStream();

var memoryStream = new MemoryStream();
_clientRequestStream.CopyTo(memoryStream);

CopyTo 需要很长时间才能将Stream 复制到另一个Stream。似乎应用程序无缘无故地停在那里,或者至少我找不到原因。

【问题讨论】:

  • 可能是因为源流仍处于打开状态并等待更多数据??
  • @mellamokb:那我怎么知道?
  • 这当然不是 CopyTo 的错!源流未传送数据。可能 TCP 服务器没有关闭连接。
  • @usr:当我直接读取 NetworkStream 时,它包含数据。
  • 对不起,但我很好奇为什么这个问题得到了-2票?我遇到了这个问题,我想解决它。这里有什么奇怪的吗?

标签: c# .net network-programming streaming


【解决方案1】:

网络流保持打开状态,直到它被流的一端关闭。 CopyTo() 复制流中的所有数据,等待流结束。如果服务器没有发送数据,则流不会结束或关闭,CopyTo() 会尽职尽责地等待更多数据或流结束。流的另一端的服务器必须关闭流才能结束并返回 CopyTo()。

谷歌“TcpClient 教程”或“TcpCLient 示例”以获取一些显示您可能使用它们的其他方式的好页面,例如检查 NetworkStream.DataAvailable 以查看是否有数据等待或流是否仍然打开而没有数据。要仅读取一些数据而不等待流关闭,您可以使用 NetworkStream.Read() 或将其包装在 StreamReader 中并使用 ReadLine()。这完全取决于您要连接的服务器以及您要完成的任务。

【讨论】:

  • 我认为 CopyTo() 关闭时会返回,关于异步网络处理的教程超出了问题的范围。
  • Jason 是对的:确保接收到所有数据的唯一方法是根据内容的性质(长度前缀)或等待流关闭。 还有什么可能? TCP 提供了一个流。
  • 谢谢 Jason,至少我有了一些远见,并开始思考我应该如何解决它。
  • @SaberAmani 了解您连接到哪种服务器程序以及您期望的数据真的很有帮助。
  • 这是一个简单的代理服务器,我正在尝试编写它。有趣的一点是 Jason,DataAvailable 属性始终为真。我在一个线程中检查它。但它总是正确的。
【解决方案2】:

TCP 是一种流协议。字节可以以任意速率流动。理论上你可以得到一个字节,然后几秒钟后得到 10 个字节,几分钟后得到两个字节。

TCP 本身作为一种协议是无用的。

必须有一个高阶协议,其结构允许检测“消息”的开头和结尾。我们无法猜测您正在收听的高阶协议,您必须知道才能收听。

【讨论】:

    【解决方案3】:

    我相信这将无限期地阻塞,直到底层连接关闭,在这种情况下,我认为它会抛出一个 IOException。小心将 NetworkStream 视为普通流。 TCPClient.GetStream() 是一个很好的抽象,它为您省去了直接使用 Socket 的麻烦,但是使用 NetworkStream 进行同步操作很容易陷入此类陷阱。值得查看 NetworkStream 上的特定 MSDN 文档。

    这是一个使用异步套接字而不是 TCP 客户端的好例子:http://www.codeproject.com/Articles/83102/C-SocketAsyncEventArgs-High-Performance-Socket-Cod

    【讨论】:

    • 异步套接字在这里没有帮助。问题依然存在:如何检测流何时结束。
    • 正如 Terdiver 上面所说的,TCP 只保证字节顺序,而不保证你会收到多少字节,这就是为什么你在非本地环境中开始测试时经常遇到问题的原因。如果您对位于此之上的协议有任何控制权,那么最好构建一个缓冲区直到准备好并依赖“消息”的框架机制(有时就像换行一样简单)
    猜你喜欢
    • 2020-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-14
    • 2013-09-16
    • 2013-06-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多