TCP三次握手及状态变迁

TCP(Transmission Control Protocol) 传输控制协议。
由于 TCP 协议提供可靠的连接服务,于是采用有保障的三次握手方式来创建一个 TCP 连接

TCP控制位

ACK :确认标志

TCP首部中的确认标志,对已接受到的TCP报文进行确认,表示确认号有效

SYN:同步标志

该标志仅在三次握手建立TCP连接时有效。用于发起一个TCP的连接。

FIN :结束标志

带有该标志置位的数据包用来结束一个TCP回话,但对应端口仍处于开放状态,准备接收后续数据。

三次握手过程:

 1、客户端发送一个带SYN标志的TCP报文(报文1)到服务器端,表示希望建立一个TCP连接。

 2、服务器发送一个带ACK标志和SYN标志的TCP报文(报文2)给客户端,ACK用于对报文1的回应,SYN用于询问客户端是否准备好进行数据传输。

 3、客户端发送一个带ACK标志的TCP报文(报文3),作为报文2的回应。

四次挥手过程:

1.客户端发送一个FIN报文(报文4)给服务器,表示我将关闭客户端到服务器端这个方向的连接。

2.服务器收到报文4后,发送一个ACK报文(报文5)给客户端,序号为报文4的序号加1

3.服务器发送一个FIN报文(报文6)给客户端,表示自己也将关闭服务器端到客户端这个方向的连接。

4.客户端收到报文6后,发回一个ACK报文(报文7)给服务器,序号为报文6的序号加1

至此,一个TCP连接就关闭了。

TCP连接状态:

1.CLOSED

初始状态,表示TCP连接是“关闭着的”或“未打开的”。

2.LISTEN  

表示服务器端的某个SOCKET处于监听状态,可以接受客户端的连接。

3.SYN_RCVD

表示接收到了SYN报文。在正常情况下,这个状态是服务器端的SOCKET在建立TCP连接时的三次握手会话过程中的一个中间状态,很短暂。当TCP连接处于此状态时,再收到客户端的ACK报文,它就会进入到ESTABLISHED状态。

4.SYN_SENT

这个状态与SYN_RCVD状态相呼应,当客户端SOCKET执行connect()进行连接时,它首先发送SYN报文,然后随即进入到SYN_SENT状态,等待服务端的发送三次握手中的第2个报文。SYN_SENT状态表示客户端已发送SYN报文。

5.ESTABLISHED 

表示TCP连接已经成功建立。

6. FIN_WAIT_1 

7. FIN_WAIT_2

这两种状态都是表示等待对方的FIN报文。FIN_WAIT_1状态是当SOCKETESTABLISHED状态时,它想主动关闭连接,向对方发送了FIN报文,此时该SOCKET进入到FIN_WAIT_1状态。而当对方回应ACK报文后,则进入到FIN_WAIT_2状态。正常情况下,无论对方处于何种情况,都应该马上回应ACK报文,所以FIN_WAIT_1状态一般是比较难见到的。

8.TIME_WAIT

表示收到了对方的FIN报文,并发送出了ACK报文。等待足够的时间(2*MSL),以确保远程TCP接收到连接中断请求的确认。MSL为最大分段生存期,指一个TCP报文在Internet上的最长生存时间。

9.CLOSING

这种状态在实际情况中应该很少见。正常情况下,当一方发送FIN报文后,按理来说是应该先收到(或同时收到)对方的ACK报文,再收到对方的FIN报文。但是CLOSING状态表示一方发送FIN报文后,并没有收到对方的ACK报文,反而却也收到了对方的FIN报文。这种情况一般是双方几乎同时关闭SOCKET连接是发生。

10.CLOSE_WAIT

表示正在等待关闭。当对方close()一个SOCKET后发送FIN报文给自己,你的系统将会回应一个ACK报文给对方,此时TCP连接则进入到CLOSE_WAIT状态。然后,你需要检查自己是否还有数据要发送给对方,如果没有,那就可以close()这个SOCKET并发送FIN报文给对方,即关闭自己到对方这个方向的连接。有数据的话则看程序的策略,继续发送或丢弃。简单地说,当你处于CLOSE_WAIT状态下,需要完成的事情是等待你去关闭连接。

11.LAST_ACK

当被动关闭的一方在发送FIN报文后,等待对方的ACK报文的时候,就处于LAST_ACK状态。当收到对方的ACK报文后,也就可以进入到CLOSED可用状态了。

TCP相关疑问

1.为什么在TCP协议里,建立连接是三次握手,而关闭连接却是四次握手呢?

因为当处于LISTEN 状态的服务器端SOCKET当收到SYN报文(客户端希望新建一个TCP连接)后,它可以把ACK(应答作用)和SYN(同步作用)放在同一个报文里来发送给客户端。但在关闭TCP连接时,当收到对方的FIN报文时,对方仅仅表示对方没有数据发送给你了,但未必你的所有数据都已经全部发送给了对方,所以你大可不必马上关闭SOCKET(发送一个FIN报文),等你发送完剩余的数据给对方之后,再发送FIN报文给对方来表示你同意现在关闭连接了,所以通常情况下,这里的ACK报文和FIN报文都是分开发送的。

2.为什么TIME_WAIT 状态还需要等2*MSL秒之后才能返回到CLOSED 状态呢?

 因为虽然双方都同意关闭连接了,而且握手的4个报文也都发送完毕,按理可以直接回到CLOSED 状态(就好比从SYN_SENT 状态到ESTABLISH 状态那样),但是我们必须假想网络是不可靠的,你无法保证你最后发送的ACK报文一定会被对方收到,就是说对方处于LAST_ACK 状态下的SOCKET可能会因为超时未收到ACK报文,而重发FIN报文,所以这个TIME_WAIT 状态的作用就是用来重发可能丢失的ACK报文。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值