5

我有一个客户端-服务器应用程序,其中每一方都通过 TCP 套接字与另一方通信。

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

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

编辑 有时以下write()也有一个正的返回值,好像一切顺利。

4

3 回答 3

8

您对返回值的write()含义感到困惑。这并不意味着“对等方获得了数据并确认了它”。相反,它的意思是,“我缓冲了这么多字节以发送给对等方,现在它们是我的责任,所以你可以忘记它们(而且我没有任何未决错误)”。

也就是说,如果 TCP 堆栈接受写入并返回n个字节,这并不意味着它们已经被写入,只是排队等待写入。在堆栈放弃并向您返回错误之前,可能需要一些时间,可能是在它开始发送网络流量后 30 秒。在那段时间里,您可以进行多次调用,这些调用write()成功地将数据排队等待发送。(如果peer已经消失,写错误将在c.30s内返回,或者如果可以联系到peer并立即发送RST数据包以指示连接已死,则立即返回。)

于 2013-03-14T10:32:15.880 回答
3

这与 TCP/IP 的工作方式有关,可以粗略地描述为两个大部分独立的半连接。当您关闭服务器上的套接字时,客户端被告知它将不会从C<-S半连接中接收更多数据,立即唤醒read(),但与C->S方向无关。它仅在尝试发送一些数据后才会收到重置连接的回复。我推荐TCP/IP 指南以获取更多详细信息。

有时你可以两次的原因write()是你写得比往返时间快,并且可以write()在回复第一个之前挤一秒钟。

于 2013-03-14T10:12:04.140 回答
0

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

在套接字上获得 select() 超时后(没有收到任何东西,但应该收到),'system("ping -c 1 -w 1 server");' 命令被激活。如果服务器启动并且只是滞后,ping 命令将在不到 0.1 秒内返回。否则(服务器宕机),ping 命令将在 1 秒后返回。

于 2014-03-08T14:37:36.483 回答