我有一个客户端 - 服务器应用程序,其中每一方通过TCP套接字与另一方通信。
我正确建立了连接,然后在客户端在套接字上写入任何数据之前使服务器崩溃
我看到的是第一个write()
尝试(客户端)成功并返回实际写入的字节数,而后面的返回(如我所料)-1
(接收SIGPIPE
1}})和errno=EPIPE
。
为什么即使套接字已经关闭,第一个write()
也会成功?
修改
有时候下面的write()
也会有一个正的回报值,好像一切顺利。
答案 0 :(得分:5)
您对write()
的返回值的含义感到困惑。这并不意味着,“同行得到了数据并承认了它”。相反,它意味着,“我缓冲了太多的字节发送给同行,他们现在是我的责任,所以你可以忘记它们(我没有任何未决的错误)”。
也就是说,如果TCP堆栈接受写入并返回 n 字节,这并不意味着它们已经被写入,只是排队等待写入。在堆栈放弃并向您返回错误之前,它可能需要一些时间,也就是它开始发送网络流量后30秒。在此期间,您可以对write()
进行多次调用,这些调用成功排队数据以进行发送。 (如果对等体消失,写入错误将在c.30s中返回,或者如果可以联系对等体并立即发送RST数据包以指示连接已经死亡,则会立即返回。)
答案 1 :(得分:3)
这与TCP / IP的工作方式有关,可以粗略地描述为两个主要是独立的半连接。当您关闭服务器上的套接字时,会告知客户端它不会从C<-S
半连接接收更多数据,立即唤醒read()
,但不会关注C->S
方向。只有在尝试发送一些数据后才会重置连接。我建议TCP/IP Guide了解更多详情。
有时你可以write()
两次的原因是你写得比往返时间快,并且可以在回复第一个之前挤压第二个write()
。
答案 2 :(得分:0)
我正在使用以下方法检测断开连接的服务器条件:
在套接字上获取select()超时后(虽然应该没有收到), 'system(“ping -c 1 -w 1 server”);'命令已激活。 如果服务器已启动并且只是滞后,则ping命令将在不到0.1秒的时间内返回。 否则(服务器关闭),ping命令将在1秒后返回。