省略FIN,发送FIN-ACK

时间:2014-01-27 20:01:18

标签: linux sockets networking tcp

正如它在维基百科上写的那样,关闭TCP连接应该使用数据包FIN->(FIN,ACK) - > ACK。但是当我使用close()函数关闭套接字时我没有看到FIN数据包,从服务器到客户端立即发送(FIN,ACK)数据包,然后客户端也通过发送(FIN,ACK)关闭连接,服务器响应ACK数据包。那么丢失的FIN数据包在哪里(也许它合并到FIN,ACK)?

2 个答案:

答案 0 :(得分:7)

关闭顺序也可以不同,不需要在同一个数据包中包含FIN + ACK:

  • ACK只是确认收到数据(例如收到的所有内容,直到给定的序列号)
  • 数据包将被重新发送,直到收到一个ACK
  • FIN只是说发送FIN的一方不会发送更多数据。如果它仍然会收到数据,它不会提供任何信息。
  • 与所有其他数据包一样,FIN将被重新发送,直到确认收据

HTTP之类的协议支持单向关闭,例如客户端发送请求数据,然后发送FIN以通知服务器它将不再发送数据。但它仍然会收到服务器发送的数据。服务器将像之前的所有数据一样确认FIN。一旦服务器完成,它将发送自己的FIN,客户端确认。在这种情况下,你有

1. client: FIN  (will not send more) 
2. server: ACK (received the FIN)
.. server: sends more data..., client ACKs these data 
3. server: FIN (will not send more)
4. client: ACK (received the FIN)

请注意,您在步骤#1中看到的数据包也可能包含ACK。但是这个ACK只是确认服务器之前发送的数据。如果服务器没有更多要发送的数据,它也可能会关闭连接。在这种情况下,步骤2 + 3可以合并,例如,服务器发送FIN + ACK,其中ACK确认客户端收到的FIN。

如果一方发送其FIN,则该连接被称为半封闭。一旦双方发送他们的FIN并收到FIN的ACK,它就完全关闭,无论他们是在3包还是4包中这样做。

答案 1 :(得分:0)

您必须已经收到FIN才能发送FIN / ACK。你是否因为阅读EOS而接近?