1、TCP三次握手
1、客户端向服务器发送TCP SYN报文(SYN=1),并指定初始序号seq=x,不带数据。(消耗序号)
2、服务器收到SYN报文,用SYN,ACK报文回复(SYN=1,ACK=1)。与此同时,服务器为该连接分配缓冲区和变量,并指定服务器初始序号seq=y,返回确认号ack=x+1,不带数据。(消耗序号)
3、客户端收到SYN,ACK报文,用ACK报文回复(ACK=1),有可能包含数据。seq=x+1,ack=y+1。(若无数据,则这个报文不消耗序号,故在服务器开始发送数据的时候,序号seq=y+1,确认号ack=x+1)
2、TCP四次挥手
-
客户端执行主动关闭,发送第一个TCP FIN报文(FIN=1),序号seq=x。(消耗序号)
-
服务器收到FIN报文,通知应用程序,执行被动关闭。返回一个ACK报文(ACK=1),序号seq=y,确认号ack=x+1。之后客户端不可再发送数据,而服务端仍然可以发送数据。(若无数据,则报文不消耗序号)
-
服务器进程释放,不再发送数据,发送FIN ACK报文回复(FIN=1,ACK=1),序号seq=y(若在关闭等待过程中有数据传输,则序号seq为一个新序号z),确认号ack=x+1。(消耗序号)
-
客户端收到FIN ACK报文,用ACK报文回复(ACK=1),序号seq=x+1,确认号ack=y+1(或z+1)。再等待2MSL((Maximum Segment Lifetime)时间后{MSL(Maximum Segment Lifetime),报文段最大生存时间},关闭连接。
ps:关闭连接期间,服务器可以传送数据,客户端可以接收数据,这样的状态称为TCP的半关闭.
RFC 793中定义MSL为2分钟,实际应用为30秒,60秒,120秒。
Linux 系统里 2MSL 默认是 60 秒,单MSL是30秒,在Linux 内核参数名称为 TCP_TIMEWAIT_LEN。可以修改它,并重新编译内核,也可修改/proc/sys/net/ipv4/tcp_fin_timeout值。
3、TCP的11种状态