2013-03-14 47 views
3

我有一个客户端 - 服务器应用程序,其中每端通过TCP套接字与另一端进行通信。在由对等关闭的TCP套接字上进行写入

我正确地建立了连接,然后在服务器崩溃之前,客户端在套接字上写入任何数据。
我看到的第一个write()尝试(客户端)是成功的,它返回实际写入字节数,而下面的返回(如我所料)-1(接收SIGPIPE)和errno=EPIPE

即使套接字已关闭,为什么第一个write()成功?

编辑 有时也以下write()有正收益值,如一切顺利。

回答

5

您对write()的返回值意味着什么感到困惑。这并不意味着“同行得到了数据并承认了它”。相反,它的意思是,“我缓存了很多字节发送给对等方,他们现在是我的责任,所以你可以忘记它们(并且我没有任何挂起的错误)”。即,如果TCP堆栈接受写入并返回字节,这并不意味着它们已经写入,只是排队等待写入。在堆栈放弃并向您返回错误之前,它需要一段时间,也就是在开始发送网络通信之后30秒。在此期间,您可以拨打write()进行多次呼叫,这些呼叫已成功排队发送数据。 (如果对等体已经消失,写入错误将在30秒内返回,或者立即如果可以联系对等体并立即发送RST数据包以指示连接已死亡)。

3

这与TCP/IP的工作方式有关,可以粗略描述为两个大多数独立的半连接。当您关闭服务器上的套接字时,客户端会被告知它不会从C<-S半连接接收到更多数据,立即唤醒read(),但不会向C->S方向发送数据。它只会在尝试发送一些数据后获得重置连接的回复。我建议TCP/IP Guide进一步的细节。

有时您可以两次输入write()的原因是,您的回写速度比往返时间快,并且可以在回复第一个回复之前挤出第二个write()

0

我正在使用以下方法来检测断开连接的服务器状态:

'在系统(“ping -c 1 -w 1 server”); “命令被激活。 如果服务器启动并刚刚落后,ping命令将在不到0.1秒的时间内返回。 否则(服务器关闭),ping命令将在1秒内返回。