码迷,mamicode.com
首页 > 其他好文 > 详细

TCP状态转换

时间:2015-11-18 07:08:07      阅读:479      评论:0      收藏:0      [点我收藏+]

标签:tcp


技术分享


状态说明:

CLOSED:表示初始状态

LISTEN:表示服务器端的某个SOCKET处于监听状态,可以接受连接了

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

ESTABLISHED:表示连接已经建立了

FIN_WAIT_1:1和2真正的含义是表示等待对方的FIN报文,而这两种状态的区别是:FIN_WAIT_1状态实际上是当SOCKET在ESTABLISHE态时,它想主动关闭连接,向对方发送了FIN报文,此时该SOCKET即进入到FIN_WATI_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_WAID_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可用状态了

 

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

因为服务器端的LISTEN状态下的SOCKET当收到SYN报文建连接请求后,它可以把ACKSYN(ACK起应答作用,而SYN起同步作用)放在一个报文时发送。但是关闭连接,当收到对应FIN报文通知时,它仅仅表示对方没有数据发送给你了,但未必你所有的数据都全部发送给对方了,所以你可以未必马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方表示同间现在可以关闭连接了,所以这里的ACK报文和FIN报文多数情况下都是分开发送的

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

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

 

技术分享



建立连接协议(三次握手)

(1)   客户端发送一个带SYN标志的TCP报文到服务器,这是三次握手过程中的报文1

(2)   服务器端回应客户端的,这是三次握手中的第二个报文,这个报文同时带ACK标志和SYN标志,因此它表示对客户端SYN报文回应

同时又标志SYN给客户端,询问客户端是否准备好进行数据通讯

3)客户必须再次回应服务段一个ACK报文,这是报文段3

 

 

连接终止协议(四次断开)

由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这原则是一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一下FIN只意味这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方执行关闭,而

另一方执行被动关闭

(1)   TCP客户端发送一个FIN,用来关闭客户端到服务器的数据传送(报文段4

(2)   服务器收到这个FIN,这它发回一个ACK,确认序号为收到序号加1(报文段5)。和SYN一样,一个FIN将占用一个序号

(3)   服务器关闭客户端连接,发送一个FIN给客户端(报文段6

(4)   客户段发回ACK报文确认,并将确认序号设置为收到序号加1(报文段7





TCP状态转换

标签:tcp

原文地址:http://reid21.blog.51cto.com/8257755/1713819

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!