【问题标题】:.NET NetworkStream closed, how to be sure all data is read?.NET NetworkStream 关​​闭,如何确保读取所有数据?
【发布时间】:2010-06-18 07:55:34
【问题描述】:

我有一个开放的 TCP 连接,并使用 NetworkStream.BeginRead() 进行读取。一旦在任一端关闭连接,就会调用回调并且流对象无用 - 就像文档中所说,EndRead() 抛出 IOException 或 ObjectDisposedException 取决于在这种情况下终止连接的一端。

是否保证在最后一次成功的 EndRead(和 re-BegingRead)和断开连接之间没有任何数据丢失,尤其是在我最后这样做的时候?如果不是,如果我结束连接,我是否必须在断开连接时手动 NetworkStream.Read() 以确保没有任何内容未读?

【问题讨论】:

    标签: c# networking tcpclient networkstream


    【解决方案1】:

    在这种情况下使用的模式是使用 BeginRead 来读取流(就像您正在做的那样)并在回调方法中处理“流中的更多数据”情况。
    回调方法调用 EndRead 并收集从流中读取的数据(通常通过将其附加到 StringBuilder 实例)然后再次调用 BeginRead。一旦 EndRead 返回 0 字节,就可以保证不再有数据要从流中读取。

    以下是您可能会发现有用的文档:Using async client sockets

    我注意到那里没有具体说明 0 字节返回是保证,所以我理解你在这里的困惑,但这个例子很清楚,这是你退出阅读的信号。

    【讨论】:

    • 哇哦!我知道一些正确的东西,但绝对没有其他人知道足以确认或否认!呃,等一下,我为什么对此感到高兴?
    • 我要复活这个,希望也许这个(非常相关的)问题会得到回答:EndRead 如何产生 0 字节读取,如果调用 EndRead 的唯一方法是回调到BeginRead,需要传输数据才能执行?我应该只发送一个零字节的响应吗?
    • 好吧,现在您正在谈论写入 到流而不是从中读取。这有点不同。你有一个悬而未决的问题要链接吗?本质上,您不必专门写零字节,您只需完成响应即可。
    • 我没有悬而未决的问题,没有。我测试了将数据写入流并在数据被分块读取后在另一端调用BeginRead。当没有更多数据时,BeginRead 将“阻塞”,因为回调永远不会被调用。基本上:EndRead 不能返回零字节。我最终添加了一个描述通信长度的标题来解决这个问题。
    猜你喜欢
    • 1970-01-01
    • 2014-11-21
    • 1970-01-01
    • 1970-01-01
    • 2020-10-01
    • 1970-01-01
    • 2014-12-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多