TCP状态机详解(TCP/IP)

 

第二章、正常的TCP连接和断开状态切换介绍

 

图2-1 正常的TCP连接和断开状态切换过程

 

.连接的建立(三次握手)

a: 第一次握手:建立连接。客户端发送连接请求报文段,将SYN位置为1,Sequence Number为J;然后,客户端进入SYN_SEND状态,等待服务器的确认;

b: 第二次握手:服务器收到SYN报文段。服务器收到客户端的SYN报文段,需要对这个SYN报文段进行确认,设置Acknowledgment Number为J+1(Sequence Number+1);同时,自己自己还要发送SYN请求信息,将SYN位置为1,SequenceNumber为K;服务器端将上述所有信息放到一个报文段(即SYN+ACK报文段)中,一并发送给客户端,此时服务器进入SYN_RECV状态;

c: 第三次握手:客户端收到服务器的SYN+ACK报文段。然后将Acknowledgment Number设置为K+1,向服务器发送ACK报文段,这个报文段发送完毕以后,客户端和服务器端都进入ESTABLISHED状态,完成TCP三次握手。

下图为同时打开过程的状态切换图

2.结束连接(四次挥手)

a: 第一次挥手:主机1(可以使客户端,也可以是服务器端),设置Sequence Number和Acknowledgment Number,向主机2发送一个FIN报文段;此时,主机1进入FIN_WAIT_1状态;这表示主机1没有数据要发送给主机2了;

b: 第二次挥手:主机2收到了主机1发送的FIN报文段,向主机1回一个ACK报文段,Acknowledgment Number为Sequence Number加1;主机1进入FIN_WAIT_2状态;主机2告诉主机1,我也没有数据要发送了,可以进行关闭连接了;

c: 第三次挥手:主机2向主机1发送FIN报文段,请求关闭连接,同时主机2进入CLOSE_WAIT状态;

d: 第四次挥手:主机1收到主机2发送的FIN报文段,向主机2发送ACK报文段,然后主机1进入TIME_WAIT状态;主机2收到主机1的ACK报文段以后,就关闭连接;此时,主机1等待2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,主机1也可以关闭连接了。

疑问:
为什么要进行三次握手?为什么要四次挥手?

1、  三次握手最主要是防止已过期的连接再次传到被连接的主机。如果采用两次的话,会出现下面这种情况。比如是A机要连到B机,结果发送的连接信息由于某种原因没有到达B机;于是,A机又发了一次,结果这次B收到了,于是就发信息回来,两机就连接。
传完东西后,断开。结果这时候,原先没有到达的连接信息突然又传到了B机,于是B机发信息给A,然后B机就以为和A连上了,这个时候B机就在等待A传东西过去。

2、  四次挥手主要是因为TCP是全双工的传输协议。所以关闭两个通道最少也应该像连接那样,有三个报文。但是为了实现TCP的半关闭功能(即有一条单向的传输关闭,一条单向的传输正常工作)。所以有四个报文,就是四次挥手。
第三章、TCP的同时连接和同时断开过程
1、TCP的同时进行连接

1. PC1的应用程序使用端口7777与PC2的端口8888 执行主动打开

2. PC2的应用程序使用端口8888与PC1的端口7777执行主动打开

3. SYN包同时打开对端,这种情况即为同时打开

TCP中,对于同时打开它仅建立一条连接而不是两条连接,状态变迁图如下:同时发送SYN包,然后收到进行确认直接进入ESTABLISHED状态,可以看到同时打开需要连接建立需要4个报文段,比三次握手多一次!

2、TCP的同时断开连接

有同时打开,理所应当的也有同时关闭的场景,TCP协议也允许同时关闭。状态变化可以看到下图了,同时发送FIN包,两端同时执行主动关闭,进入FIN_WAIT_1的状态,从FIN_WAIT_1状态收到FIN包的时候进入CLOSING状态,然后回复ACK,进入TIME_WAIT状态。

补充:

 上述的这些已经将TCP的基本的连接与断开问题完毕。但是在TCP状态机的图中仍有几条状态转换需要另外说明

a: LISTEN->SYN_SENT:服务器有时候也要打开连接

b: SYN_SENT->SYN收到:服务器和客户端在SYN_SENT状态下如果收到SYN数据报,则都需要发送SYN的ACK数据报并把自己的状态调整到SYN收到状态,准备进入ESTABLISHED。

这个过程就是同时打开连接

c: SYN_SENT->CLOSED:在发送超时的情况下,会返回到CLOSED状态。

d: SYN_收到->LISTEN:如果受到RST包,会返回到LISTEN状态。

e: SYN_收到->FIN_WAIT_1:这个迁移是说,可以不用到ESTABLISHED状态,而可以直接跳转到FIN_WAIT_1状态并等待关闭。

f: FIN_WAIT_1->CLOSING->TIME_WAIT:同时关闭的过程

e: FIN_WAIT_1->TIME_WAIT:主动方收到一个FIN/ACK一起的报文段。
2MSL等待状态:

 书中给的图里面,有一个TIME_WAIT等待状态,这个状态又叫做2MSL状态,说的是在TIME_WAIT2发送了最后一个ACK数据报以后,要进入TIME_WAIT状态,这个状态是防止最后一次握手的数据报没有传送到对方那里而准备的(注意这不是四次握手,这是第四次握手的保险状态)。这个状态在很大程度上保证了双方都可以正常结束,但是,问题也来了。

 由于插口的2MSL状态(插口是IP和端口对的意思,socket),使得应用程序在2MSL时间内是无法再次使用同一个插口的,对于客户程序还好一些,但是对于服务程序,例如httpd,它总是要使用同一个端口来进行服务,而在2MSL时间内,启动httpd就会出现错误(插口被使用)。为了避免这个错误,服务器给出了一个平静时间的概念,这是说在2MSL时间内,虽然可以重新启动服务器,但是这个服务器还是要平静的等待2MSL时间的过去才能进行下一次连接。
RST报文段:

一般来说,无论何时一个报文段发往基准的连接出现错误,TCP都会发出一个复位报文段。

基准的连接:指由目的IP地址和端口号以及源IP地址和端口号指明的连接。、

RST报文段,接收方不会进行确认。收到RST的一方将终止该连接,并通知应用层连接复位

应用场合:

1、 到不存在的端口的连接请求:服务器程序端口未打开而客户端来连接。比如主机1向主机2发送一个SYN请求,表示想要连接主机2的40000端口,但是主机2上根本没有打开40000这个端口,于是就向主机1发送了一个RST。

2、 异常终止一个连接:终止一个连接的正常方式是一方发送FIN。有事这也称为有序释放,因为所有排队数据都已发送之后才发送FIN,正常情况下没有任何数据丢失。

但是也有可能发送一个复位报文段而不是FIN来中途释放一个连接,有时也被称为异常释放。

异常释放有两个优点:(1)丢弃任何待发数据并立即发送复位报文段(优先级高)。

                                           (2)RST的接收方会区分另一端执行的是异常关闭还是正常关闭。

3、 检测半打开连接:如果一方已经关闭或者异常终止连接,而另一方却不知道。即半打开状态。比如,客户因为一些原因重启,而服务器不知道TCP已经处于半打开状态,客户再次连接,服务器将重新创建一个新的服务器程序。这样会导致服务器主机上有很多半打开的TCP连接。所以需要在重新连接的时候先发送一个RST报文段。断开之前的半打开状态的TCP连接。

4、 向一个已经关闭的连接发送报文段

5、close(sockfd)时,直接丢弃接收缓冲区未读取的数据,并给对方发一个RST。这个是由SO_LINGER选项来控制的;
 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值