只有在第二个管道发生故障时才会关闭套管

我正在通过TCP套接字测试客户端 - 服务器通信。 我用C语言编写服务器,并在Linux机器上运行它,并使用nc作为客户端进行测试。

在与客户端初始交换消息之后,服务器定期向客户端发送一些消息而没有得到任何响应。

如果我终止了客户端,我期望服务器完成的第一个send()失败并且发生EPIPE错误,但是这仅在客户端离开后第二次send()才会生效! 我杀死客户端后的第一个send()函数能够成功发送1100个字节给(我想是关闭的)套接字。 以下send()操作以EPIPE结尾。

有人能解释我这种行为吗? 这是由于我写入TCP / IP堆栈的事实,因此它可以在堆栈提供时进行交付? 如果是这样,我该如何检查连接状态? 可以肯定的是对方还在那里。


正常的TCP连接是一种四路握手。

http://en.wikipedia.org/wiki/Transmission_Control_Protocol

当你杀死客户时, FIN段从客户端发送到服务器,服务器协议栈发送ACK

在这里,如果服务器试图读取数据,读取调用将返回值为0,所以您的服务器程序可以理解对方已关闭,并且在此之后通常会关闭连接套接字。 这将允许从服务器端发送FIN ,并且在从客户端接收到最后的ACK之后,正常的4次握手将完成。

(P1阅读http://www.faqs.org/faqs/unix-faq/socket/的Q 2.1)

但是在这里,您正在从服务器写入数据,所以服务器只有在发送数据后才从客户端获得RESET 。 因此,您在第二次发送的第一次发送操作后收到错误。

所以,PL。 尝试关闭连接从客户端突然而不是4路手动,通过设置逗留选项和超时设置为0,以便您可以在第一次发送服务器端调用时发生错误(可能与EPIPE不同) (这不是一个推荐的做法,但仅限于你在这个特定情况下的理解)

Try the following option of nc, nc -L 0 to set the linger option and timeout to 0

(我还没有尝试这个选项的NC,检查详细信息在此链接http://docs.oracle.com/cd/E23824_01/html/821-1461/nc-1.html)

来自上述网站的nc示例,

Connect to TCP port, send some data and terminate the connection with 
TCP RST segment 
(instead of classic TCP closing handshake) by setting the linger option and 
timeout to 0:

$ echo "foo" | nc -L 0 host.example.com 22
链接地址: http://www.djcxy.com/p/63309.html

上一篇: Broken pipe only at the second send on a closed socket

下一篇: Does my unit test care about too much