StreamWriter确实抛出异常底层连接被破坏了吗?

时间:2012-12-13 11:01:41

标签: c# tcp connection streamwriter

我使用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。这将写入外出缓冲区并在不阻塞的情况下返回,除非缓冲区已满。由OS维护的内部缓冲区包含未发送的数据,操作系统将继续尝试发送,直到给定次数的尝试失败。 WriteLine将抛出IOException,但不一定每次都抛出..

2 个答案:

答案 0 :(得分:2)

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

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

  

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

(来自NetworkStream.Flush Method (MSDN)

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

答案 1 :(得分:1)

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

本合同中隐含的内容是该连接在您的最终被认为是可靠的。您编写的任何内容最终都位于内核内存池中的缓冲区中。这个缓冲区大大提高了程序的吞吐量,消除了程序和可变传输速率之间的松弛。一旦它在缓冲区中,操作系统就有责任确保实际发送数据。

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