tcp链接的几种状态及链接状态详解

一般状况下,一个正常的TCP链接,都会有三个阶段:

    TCP三次握手;
    数据传送;
    TCP四次挥手

里面的几个概念:

    SYN: (同步序列编号,Synchronize Sequence Numbers)
    ACK: (确认编号,Acknowledgement Number)
    FIN: (结束标志,FINish)

I. TCP三次握手

客户端发起一个和服务建立TCP连接的请求,这里是SYN(J)
服务端接受到客户端的建立请求后,返回两个信息: SYN(K) + ACK(J+1)
客户端在接受到服务端的ACK信息校验成功后(J与J+1),返回一个信息:ACK(K+1)
服务端这时接受到客户端的ACK信息校验成功后(K与K+1),再也不返回信息,后面进入数据通信阶段服务器


II. 数据通信

客户端/服务端 read/write数据包cookie


III. TCP四次握手

    客户端发起关闭请求,发送一个信息:FIN(M)
    服务端接受到信息后,首先返回ACK(M+1),代表本身已经收到消息。
    服务端在准备好关闭以前,最后发送给客户端一个 FIN(N)消息,询问客户端是否准备好关闭了
    客户端接受到服务端发送的消息后,返回一个确认信息: ACK(N+1)
    最后,服务端和客户端在双方都获得确认时,各自关闭或者回收对应的TCP连接。

IV. 详细的状态说明网络


SYN_SEND

客户端尝试连接服务端,经过open方法。也就是TCP三次握手中的第1步以后,注意是客户端状态
sysctl -w net.ipv4.tcp_syn_retries = 2 ,作为客户端能够设置SYN包的重试次数,默认5次(大约180s)引用校长的话:仅仅重试2次,现代网络够了并发


SYN_RECEIVED

服务接受建立请求的SYN后,也就是TCP三次握手中的第2步,发送ACK数据包以前
注意是服务端状态,通常15个左右正常,若是很大,怀疑遭受SYN_FLOOD攻击
sysctl -w net.ipv4.tcp_max_syn_backlog=4096 , 设置该状态的等待队列数,默认1024,调大后可适当防止syn-flood,可参见man 7 tcptcp


sysctl -w net.ipv4.tcp_syncookies=1 , 打开syncookie,在syn backlog队列不足的时候,提供一种机制临时将syn连接换出
sysctl -w net.ipv4.tcp_synack_retries = 2 ,作为服务端返回ACK包的重试次数,默认5次(大约180s)引用校长的话:仅仅重试2次,现代网络够了测试


ESTABLISHED

客户端接受到服务端的ACK包后的状态,服务端在发出ACK在必定时间后即为ESTABLISHED
sysctl -w net.ipv4.tcp_keepalive_time = 1200 ,默认为7200秒(2小时),系统针对空闲连接会进行心跳检查,若是超过net.ipv4.tcp_keepalive_probes * net.ipv4.tcp_keepalive_intvl = 默认11分,终止对应的tcp连接,可适当调整心跳检查频率
目前线上的监控 waring:600 , critial : 800this


FIN_WAIT1

主动关闭的一方,在发出FIN请求以后,也就是在TCP四次握手的第1步队列


CLOSE_WAIT

被动关闭的一方,在接受到客户端的FIN后,也就是在TCP四次握手的第2步ip


FIN_WAIT2

主动关闭的一方,在接受到被动关闭一方的ACK后,也就是TCP四次握手的第2步
sysctl -w net.ipv4.tcp_fin_timeout=30, 能够设定被动关闭方返回FIN后的超时时间,有效回收连接,避免syn-flood.同步


LASK_ACK

被动关闭的一方,在发送ACK后一段时间后(确保客户端已收到),再发起一个FIN请求。也就是TCP四次握手的第3步


TIME_WAIT

主动关闭的一方,在收到被动关闭的FIN包后,发送ACK。也就是TCP四次握手的第4步
sysctl -w net.ipv4.tcp_tw_recycle = 1 , 打开快速回收TIME_WAIT,Enabling this option is not recommended since this causes problems when working with NAT (Network Address Translation)
sysctl -w net.ipv4.tcp_tw_reuse =1, 快速回收并重用TIME_WAIT的连接, 貌似和tw_recycle有冲突,不能重用就回收?
net.ipv4.tcp_max_tw_buckets: 处于time_wait状态的最多连接数,默认为180000.


V. 相关说明

主动关闭方在接收到被动关闭方的FIN请求后,发送成功给对方一个ACK后,将本身的状态由FIN_WAIT2修改成TIME_WAIT,而必须再等2倍的MSL(Maximum Segment Lifetime,MSL是一个数据报在internetwork中能存在的时间)时间以后双方才能把状态 都改成CLOSED以关闭链接。目前RHEL里保持TIME_WAIT状态的时间为60秒

keepAlive策略能够有效的避免进行三次握手和四次关闭的动做


TCP链接状态详解

CLOSED: 表示初始状态。


LISTEN: 表示服务器端的某个SOCKET处于监听状态,能够接受链接。


SYN_SENT:在服务端监听后,客户端SOCKET执行CONNECT链接时,客户端发送SYN报文,此时客户端就进入
SYN_SENT状态,等待服务端的确认


SYN_RCVD: 表示服务端接受到了SYN报文,在正常状况下,这个状态是服务器端的SOCKET在创建TCP链接时的三
次握手会话过程当中的一个中间状态,很短暂,基本上用netstat你是很难看到这种状态的,除非你特地写了一
个客户端测试程序,故意将三次TCP握手过程当中最后一个ACK报文不予发送。所以这种状态时,当收到客户端的
ACK报文后,它会进入到ESTABLISHED状态。


ESTABLISHED:表示链接已经创建了。


FIN_WAIT_1: 这个是已经创建链接以后,其中一方请求终止链接,等待对方的FIN报文。FIN_WAIT_1状态是当
SOCKET在ESTABLISHED状态时,它想主动关闭链接,向对方发送了FIN报文,此时该SOCKET即进入到FIN_WAIT_1
状态。而当对方回应ACK报文后,则进入到FIN_WAIT_2状态,固然在实际的正常状况下,不管对方何种状况下
,都应该立刻回应ACK报文,因此FIN_WAIT_1状态通常是比较难见到的,而FIN_WAIT_2状态还有时经常能够用
netstat看到。


FIN_WAIT_2:实际上FIN_WAIT_2状态下的SOCKET,表示半链接,也即有一方要求close链接,但另外还告诉对
方,我暂时还有点数据须要传送给你,稍后再关闭链接。


TIME_WAIT: 表示收到了对方的FIN报文,并发送出了ACK报文,就等2MSL后便可回到CLOSED可用状态了。若是
FIN_WAIT_1状态下,收到了对方同时带FIN标志和ACK标志的报文时,能够直接进入到TIME_WAIT状态,而无须
通过FIN_WAIT_2状态。


CLOSING: 这种状态比较特殊,实际状况中应该是不多见,属于一种比较罕见的例外状态。正常状况下,当你
发送FIN报文后,按理来讲是应该先收到(或同时收到)对方的ACK报文,再收到对方的FIN报文。可是CLOSING状
态表示你发送FIN报文后,并无收到对方的ACK报文,反而却也收到了对方的FIN报文。什么状况下会出现此
种状况呢?其实细想一下,也不可贵出结论:那就是若是双方几乎在同时close一个SOCKET的话,那么就出现
了双方同时发送FIN报文的状况,也即会出现CLOSING状态,表示双方都正在关闭SOCKET链接。


CLOSE_WAIT: 这种状态的含义实际上是表示在等待关闭。怎么理解呢?当对方close一个SOCKET后发送FIN报文给
本身,你系统毫无疑问地会回应一个ACK报文给对方,此时则进入到CLOSE_WAIT状态。接下来呢,实际上你真
正须要考虑的事情是察看你是否还有数据发送给对方,若是没有的话,那么你也就能够close这个SOCKET,发
送FIN报文给对方,也即关闭链接。因此你在CLOSE_WAIT状态下,须要完成的事情是等待你去关闭链接。

 

LAST_ACK: 这个状态仍是比较容易好理解的,它是被动关闭一方在发送FIN报文后,最后等待对方的ACK报文。 当收到ACK报文后,也便可以进入到CLOSED可用状态了。

相关文章
相关标签/搜索