本文为学习笔记,并非原创。原文链接
TCP 报文头部结构
需重点关注的字段:
- seq序号。用来标识从TCP源端向目的端发送的字节流。
- ack确认序号。只有ACK标致为1时,ack序号才有效。
-
标志位,共六个:
- ACK:确认序号ack有效。确认方ack=发起方seq + 1
- FIN:释放一个连接。
- PSH:接收方应尽快将此报文交给给应用层。
- RST:重置连接。
- SYN:发起一个新连接。
- URG:紧急指针有效。
三次握手
为什么 TCP 连接是三次握手?两次不可以吗?
因为丢包会造成服务端空等。如果只握手两次,第二次握手时如果服务端发给客户端的确认报文段丢失,此时服务端已经准备好了收发数据(可以理解为服务端已经连接成功),而客户端一直没收到服务端的确认报文,所以客户端就不知道服务端是否已经准备好了(可以理解为客户端未连接成功),这种情况下客户端不会给服务端发数据,也会忽略服务端发过来的数据。
如果是三次握手,即便发生丢包也不会有问题。如果第三次握手客户端发的确认报文丢失,服务端在一段时间内没有收到确认报文的话就会重新进行第二次握手,也就是服务端会重发 SYN 报文段,客户端收到重发的报文段后会再次给服务端发送确认报文。
四次挥手
为什么 TCP 连接是三次握手,关闭的时候却要四次挥手?
主要是建立连接时接收者的 SYN-ACK 一同发送了,而关闭时 FIN 和 ACK 却不能同时发送,因为断开连接要处理的情况比较多,比如服务器端可能还有发送出的消息没有得到 ACK,也可能服务器资源需要释放等。所以先发一个 ACK 表示已经收到了发送方的请求,等上述情况都有了确定的处理,再发 FIN 表示接收方已经完成了后续工作。
为什么客户端发出第四次挥手的确认报文后要等 2MSL 的时间才能释放 TCP 连接?
这里同样是要考虑丢包的问题。如果第四次挥手的报文丢失,服务端没收到确认报文就会重发第三次挥手的报文,这样报文一去一回最长时间就是 2MSL,所以需要等这么长时间来确认服务端确实已经收到了。
Comments
comments powered by Disqus