3

我正在使用 这样StreamWriter的实例化Tcpstream

streamWriter = new StreamWriter(tcpClient.GetStream());    

我对以下关于异常的调用的行为感到困惑。以下两个函数预计会引发IOException令人惊讶IOException的是,当连接的服务器tcpClient断开连接并因此底层 TCP 客户端连接中断时,它们不会引发。这两行执行时不会引发任何异常。为什么 ?

streamWriter.WriteLine(strBuffer);
streamWriter.Flush();

编辑:除了专家的回复之外,这篇特别的帖子也帮助我理解了原因。 http://social.msdn.microsoft.com/Forums/sk/netfxnetcom/thread/b177a935-7430-4812-9555-f747748df1af 本质上,当调用 StreamWriter 的 WriteLine 时会调用 NetworkStream.Write,这会写入输出缓冲并返回,没有阻塞,除非缓冲区已满。操作系统维护的内部缓冲区包含未发送的数据,操作系统将继续尝试发送,直到给定次数的尝试失败。WriteLine 将抛出 IOException 但不一定每次都抛出..

4

2 回答 2

2

此问题与 无关StreamWriter,仅与 的行为有关NetworkStream

NetworkStream.Flush()是无操作的。特别是在接收者确认刷新之前发送的所有字节之前不会阻塞。

Flush 方法实现了 Stream.Flush 方法;但是,由于 NetworkStream 没有缓冲,因此对网络流没有影响。调用 Flush 方法不会引发异常。

(来自NetworkStream.Flush 方法(MSDN)

你会在某个时候得到你的例外,但这可能要晚得多。本质NetworkStream上,操作系统和操作系统都不知道 TCP 连接已经断开,因此它们不会引发异常。

于 2012-12-13T11:21:32.017 回答
1

这是 TCP 的核心方面,该协议承诺通过网络将数据可靠地传输到另一台机器。操作系统的工作是确保数据最终到达另一台机器。在您写入数据很久之后,它将尝试多次获取数据,如果没有得到确认,则在必要时重新发送 IP 数据包。当您断开机器连接时会出现这种情况。多次重试后,它不会放弃这样做。在它放弃之前可能长达一分钟。

本合同中隐含的内容是,您认为连接是可靠的。你写的任何东西都会在一个缓冲区中结束,它位于内核内存池中。这个缓冲区极大地提高了程序的吞吐量,占用了程序和可变传输率之间的时间。一旦它进入缓冲区,操作系统就有责任确保数据实际被发送。

您可以看到它的去向,直到稍后您才会从断开连接中获得异常。当缓冲区太满时,它可能发生在任何后续的 Write() 尝试中。它可能会一直延迟到您调用套接字的 Close() 方法。

于 2012-12-13T14:27:53.250 回答