TCP3次握手4次分手

http://www.cnblogs.com/rootq/articles/1377355.html  TCP三次握手解析带图

 

 

四次分手:
转自:http://justim.blog.51cto.com/740099/237548
由于 TCP连接是全双工的,因此每个方向都必须单独进行关闭。这个原则是当一方完成它的数据发送任务后就能发送一个 FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个 TCP连接在收到一个 FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。
1)客户端 A发送一个 FIN,用来关闭客户 A到服务器 B的数据传送(报文段 4)。
2)服务器 B收到这个 FIN,它发回一个 ACK,确认序号为收到的序号加 1(报文段 5)。和 SYN一样,一个 FIN将占用一个序号。
3)服务器 B关闭与客户端 A的连接,发送一个 FIN给客户端 A(报文段 6)。
4)客户端 A发回 ACK报文确认,并将确认序号设置为收到序号加 1(报文段 7)。
       状态详解:
        CLOSED: 这个没什么好说的了,表示初始状态。
  LISTEN: 这个也是非常容易理解的一个状态,表示服务器端的某个SOCKET处于监听状态,可以接受连接了。
   SYN_RCVD: 这个状态表示接受到了SYN报文,在正常情况下,这个状态是服务器端的SOCKET在建立TCP连接时的三次握手会话过程中的一个中间状态,很短暂,基本上用netstat你是很难看到这种状态的,除非你特意写了一个客户端测试程序,故意将三次TCP握手过程中最后一个ACK报文不予发送。因此这种状态时,当收到客户端的ACK报文后,它会进入到ESTABLISHED状态。
  SYN_SENT: 这个状态与SYN_RCVD遥想呼应,当客户端SOCKET执行CONNECT连接时,它首先发送SYN报文,因此也随即它会进入到了SYN_SENT状态,并等待服务端的发送三次握手中的第2个报文。SYN_SENT状态表示客户端已发送SYN报文。
   ESTABLISHED:这个容易理解了,表示连接已经建立了。
   FIN_WAIT_1: 这个状态要好好解释一下,其实FIN_WAIT_1和FIN_WAIT_2状态的真正含义都是表示等待对方的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可用状态了。
总结:
        1.为什么建立连接协议是三次握手,而关闭连接却是四次握手呢?
这是因为服务端的 LISTEN状态下的 SOCKET当收到 SYN报文的建连请求后,它可以把 ACKSYNACK起应答作用,而 SYN起同步作用)放在一个报文里来发送。但关闭连接时,当收到对方的 FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可以未必会马上会关闭 SOCKET,也即你可能还需要发送一些数据给对方之后,再发送 FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的 ACK报文和 FIN报文多数情况下都是分开发送的.
2.为什么TIME_WAIT状态还需要等2MSL后才能返回到CLOSED状态?
这是因为虽然双方都同意关闭连接了,而且握手的 4个报文也都协调和发送完毕,按理可以直接回到 CLOSED状态(就好比从 SYN_SEND状态到 ESTABLISH状态那样);但是因为我们必须要假想网络是不可靠的,你无法保证你最后发送的 ACK报文会一定被对方收到,因此对方处于 LAST_ACK状态下的 SOCKET可能会因为超时未收到 ACK报文,而重发 FIN报文,所以这个 TIME_WAIT状态的作用就是用来重发可能丢失的 ACK报文。

 

你可能感兴趣的:(TCP3次握手4次分手)