三次握手
第一次握手:客户端发送TCP包,置SYN标志位为1,将初始序号X,保存在包头的序列号(seq)里
第二次握手:服务端回应确认包,置SYN标志位为1,置ACK为X+1,将初始序列号Y,保存在包头序列号里
第三次握手: 客户端对服务端的确认包进行确认,置SYN标志位为0,置ACK为Y+1,置序列号为Z
TCP建立连接为什么是三次握手,而不是两次或四次?
TCP,名为传输控制协议,是一种可靠的传输层协议,IP协议号为6。
顺便说一句,原则上任何数据传输都无法确保绝对可靠,三次握手只是确保可靠的基本需要。
第一次握手服务端可以确认自己收报文与客户端发报文功能都正常
第二次握手客户端确认自己收发报文与服务端收发报文功能都正常,也就认为连接已建立
第三次,服务端确认双方都能够正常通信
如果不进行第三次握手,服务端对客户端的请求进行回应(第二次握手)后,就会理所当然的认为连接已建立,而如果C并没有收到S的回应呢?此时,C仍认为连接未建立,S会对已建立的连接保存必要的资源,如果大量的这种情况,S会崩溃。
因此第三次握手是必要的。
四次挥手
四次挥手
四次挥手
先由客户端向服务器端发送一个FIN,请求关闭数据传输。
当服务器接收到客户端的FIN时,向客户端发送一个ACK,其中ack的值等于FIN+SEQ
然后服务器向客户端发送一个FIN,告诉客户端应用程序关闭。
当客户端收到服务器端的FIN是,回复一个ACK给服务器端。其中ack的值等于FIN+SEQ
为什么要四次挥手?
确保数据能够完整传输。
当被动方收到主动方的FIN报文通知时,它仅仅表示主动方没有数据再发送给被动方了。
但未必被动方所有的数据都完整的发送给了主动方,所以被动方不会马上关闭SOCKET,它可能还需要发送一些数据给主动方后,
再发送FIN报文给主动方,告诉主动方同意关闭连接,所以这里的ACK报文和FIN报文多数情况下都是分开发送的。
TCP报文格式图:
上图中有几个字段需要重点介绍下:
(1)序号:Seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记。
(2)确认序号:Ack序号,占32位,只有ACK标志位为1时,确认序号字段才有效,Ack=Seq+1。
(3)标志位:共6个,即URG、ACK、PSH、RST、SYN、FIN等,具体含义如下:
(A)URG:紧急指针(urgent pointer)有效。
(B)ACK:确认序号有效。
(C)PSH:接收方应该尽快将这个报文交给应用层。
(D)RST:重置连接。
(E)SYN:发起一个新连接。
(F)FIN:释放一个连接。
需要注意的是:
(A)不要将确认序号Ack与标志位中的ACK搞混了。
(B)确认方Ack=发起方Req+1,两端配对。
参考文献: