TCP三次握手四次挥手和11中状态

TCP三次握手建立连接


第一次握手:客户端发送SYN=1(SYN的标志位设置为1),初始化一个序列号(seq=x)。
第二次握手:服务端收到请求,确认客户端的SYN(ack=x+1)发送ACK=1,SYN=1(SYN和ACK标志位设为1)并自己初始化一个seq序列号(seq=y)。
第三次握手:客户端向服务端发送确认ACK=1(ACK标志位等于1),加seq=x+1,ack=y+1确认

三次握手的tcp四种状态及变迁
LISTEN
服务端状态,应用程序打开监听端口,处理来自客户端TCP端口的连接。
SYN_SENT
客户端状态,当客户端通过应用程序connect()连接时,客户端TCP发送SYN标记主动建立连接,此时状态为SYN_SENT
SYN_RECV
服务端状态,当收到客户端SYN封包后,服务端会发送一个SYN及ACK确认到客户端,再等待对方连接确认,这时状态为SYN_RECV,如果发现有很多SYN_RCVD状态,可能受到了SYN FLood的Dos攻击
ESTABLISHED
当客户端回复正确的ack值后,就建立一个打开的连接,客户端和服务端就都进入ESTABLISHED状态,此时便可以PSH数据

TCP四次挥手


1.A对B说,我传给你的最后一个数据是u-1(seq=u),我发完了,现在想走了(FIN=1),你回个话。(FIN报文段即使不携带数据,也要消耗一个序号)
2.B对A说,你传给我的最后一个数据是u-1(ack=u+1,之前的报文段消耗了一个序号),我下一步要发送的数据是从v开始的(seq=v)。你发送完了,可是我没有发送完啊,等着让我发完!然后B就开始把剩下的数据给A。(如果B还有数据要给A的话)
3.B的剩余数据发送完之后,就对A说,我发送给你的最后一个数据的序号是w-1(seq=w),你传给我的最后一个数据是u-1(ack=u+1),现在我的数据也发完了,我想走了(FIN=1)。4.A对B说我给你的最后一个数据是u-1(seq=u+1),我收到你的最后一个数据是w-1(ack=w+1,FIN报文要消耗掉一个序号),你可以走了。

FIN_WAIT1
客户端调用close()关闭连接后,TCP发出FIN标记主动关闭连接,然后进入FIN_WAIT1状态,等待远程TCP连接中断或者确认。
CLOSE_WAIT
被动关闭状态,TCP接收到FIN后,就发送ack回应客户端的FIN标识封包,然后就进入了CLOSE_WAIT状态。
FIN_WAIT2
半关闭状态,主动关闭端(也就是客户端调用close()后)接收到ack确认后,此时进入FIN_WAIT2状态,该状态下,客户端应用程序依然能接收数据。
LAST_ACK
服务端发送确认中断后,也发送FIN关闭,然后进入LAST_ACK最后确认关闭状态
TIME_WAIT
在主动关闭端接收到FIN后,TCP就发送ACK,并进入TIME-WAIT状态,该状态持保持由内核参数默认等待2MSL,之后主动关闭方也进入CLOSED状态关闭连接。
time_wait优化

1
2
3
4
net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。
注客户端是nat模式、负载均衡情况下不要打开recycle

net.ipv4.tcp_fin_timeout=30 表示如果套接字由本端要求关闭,那么这个参数将决定它保持在FIN-WAIT-2状态的时间,默认120s。

CLOSED
TCP连接关闭,被动关闭端在接收到ack包后,进入CLOSED状态关闭TCP连接