如果服务器首先关闭套接字会发生什么?

时间:2012-08-20 05:11:06

标签: linux sockets unix network-programming

情况如下:我有2台机器,A和B. A监听端口p。 B创建一个套接字s1并连接到p。 A接受套接字s2中的连接。目前,A和B可以通过套接字相互通信。

但是,如果我在A中终止该程序,然后在一段时间后重启该程序,B不知道,因为在此期间它没有向A发送任何数据。现在B开始通过s1向A写入数据。接下来会发生什么?为什么呢?

实际上我发现write调用没有失败,但A仍然没有得到数据。更重要的是,如果我将s1放入epoll设备,我发现epoll_wait返回EPOLLERR | EPOLLHUP之后返回的事件为write。为什么呢?

不幸的是,在这种情况下,它似乎丢失了数据,因为`write'调用没有失败,但A无法获取数据。任何解决方案?

3 个答案:

答案 0 :(得分:2)

  1. 当您杀死已建立套接字的程序时,它会将RST发送到所有其他端。因此B应该在s1上接收RST,并且s1上的所有未来调用都将返回错误。但是有些防火墙可能会过滤掉RST数据包,你可以用tcpdump检查RST数据包。

  2. 如果B在步骤1中没有收到RST数据包,当它继续向A发送其他数据包(写入)时,A将使用RST数据包进行回复,并且一旦B接收到该数据,B上的所有将来呼叫都将返回错误RST。

  3. 如果B在步骤2中也没有收到RST数据包,经过一段时间(写入超时)后,B将断开连接,以后B上的所有呼叫都将返回错误。

  4. 你可以看到,写入调用很少返回错误,如果数据包发送则返回成功,不关心远程端是否收到数据包。

    在你的情况下,你在调用epoll_wait时没有得到EPOLLHUP,但是在收到RST或写入超时之后

答案 1 :(得分:2)

如果套接字的另一端已经关闭,它实际上是可读的,read(或recv)调用将返回零,表示另一端的套接字已正常关闭

答案 2 :(得分:1)

您写入了断开连接的流(即使您的计算机不知道它已断开连接。由于您说“接受连接”,我假设您在两台计算机之间设置了TCP连接。)

如果您正在谈论UDP,则没有侦听/连接/接受,并且数据将被发送到在addr / port处侦听的任何内容。但你不是在谈论UDP。 [编辑说明结论:]你正在将数据写入一个死连接(在某些时候,很明显连接已经死了,现在你已经尝试使用它了)。写入数据不会告诉您对方是否收到了数据,成功告诉您已将数据排队等待发送。