我正在通过TCP套接字测试客户端 - 服务器通信。我用C编写了服务器,我在Linux机器上运行它,我正在使用nc
作为客户端进行测试。
服务器在与客户端初始交换消息后发送一些消息 消息定期发送给客户端而不会得到任何响应。
如果我杀了客户端,我希望服务器完成的第一个send()
失败
EPIPE
错误,但结果仅在客户端消失后的第二个send()
出现!
我杀死客户端后的第一个send()
能够成功发送1100个字节到(我想已关闭)套接字。以下send()
操作以EPIPE
结束时结束。
有人可以解释我这种行为吗? 是因为我写入TCP / IP堆栈,所以它由堆栈决定 什么时候可以提供? 如果是,我该如何检查连接状态?确保同伴还在那里。
答案 0 :(得分:4)
正常TCP连接是四次握手。
http://en.wikipedia.org/wiki/Transmission_Control_Protocol
当你杀死客户端时, FIN 段从客户端发送到服务器,服务器协议栈发送 ACK 。
此处如果服务器尝试读取数据,则读取调用将返回值0,因此您的服务器程序可以理解对等体已关闭,并且通常会在此之后关闭连接套接字。这将允许从服务器端发送 FIN ,并在从客户端收到最后一个 ACK 后完成正常的4路握手。
(Pl阅读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