为何TCP三次握手却要四次挥手?什么是TCP状态?

TCP是什么?

TCP(Transmission Control Protocol 传输控制协议)是一种面向连接(连接导向)的,可靠的,基于IP的传输层协议。
在这里插入图片描述

TCP的头部格式

tcp头部信息

  • TCP源端口(SourcePort):16位的源端口其中包含发送方应用程序对应的端口。源端口和源IP地址标示报文发送端的地址。
  • TCP目的端口(Destination port):16位的目的端口域定义传输的目的。这个端口指明报文接收计算机上的应用程序地址接口。
  • TCP序列号(序列码SN,Sequence Number): 表示我这个报文是第几个
  • TCP应答号(Acknowledgment Number简称ACK Number或简称为ACK Field):表示我期望收到另一端的下一包数据的编号
  • 头长(Header Length):TCP的头部大小,只是TCP头的长度
  • 保留(Reserved):4位值域,这些位必须是0。为了将来定义新的用途所保留
  • 标志(Code Bits):比较长在下面介绍
  • 窗口大小(Window Size):表示TCP接收或发送窗口的剩余空间用于TCP流量控制
  • 校验位(Checksum):发送一个基于内容计算的数值以确保发送的数据和接收端的数据一致
  • 优先指针(紧急,Urgent Pointer):16位,指向后面是优先数据的字节,在URG标志设置了时才有效。如果URG标志没有被设置,紧急域作为填充。加快处理标示为紧急的数据段。
  • 选项(Option):长度不定,但长度必须以是32bits的整数倍。常见的选项包括MSS、SACK、Timestamp等等,后续的内容会分别介绍相关选项。
标志位介绍
  • CWR(Congestion Window Reduce):拥塞窗口减少标志被发送主机设置,用来表明它接收到了设置ECE标志的TCP包,发送端通过降低发送窗口的大小来降低发送速率
  • ECE(ECN Echo):ECN响应标志被用来在TCP3次握手时表明一个TCP端是具备ECN功能的,并且表明接收到的TCP包的IP头部的ECN被设置为11。更多信息请参考RFC793。
  • URG(Urgent):该标志位置位表示紧急(The urgent pointer) 标志有效。该标志位目前已经很少使用参考后面流量控制和窗口管理部分的介绍。
  • ACK(Acknowledgment):取值1代表Acknowledgment Number字段有效,这是一个确认的TCP包。

PSH(Push):该标志置位时,一般是表示发送端缓存中已经没有待发送的数据,接收端不将该数据进行队列处理,而是尽可能快将数据转由应用处理。在处理 telnet 或 rlogin 等交互模式的连接时,该标志总是置位的。

RST(Reset):用于复位相应的TCP连接。通常在发生异常或者错误的时候会触发复位TCP连接。

SYN(Synchronize):同步序列编号(Synchronize Sequence Numbers)有效。该标志仅在三次握手建立TCP连接时有效。它提示TCP连接的服务端检查序列编号,该序列编号为TCP连接初始端(一般是客户端)的初始序列编号。在这里,可以把TCP序列编号看作是一个范围从0到4,294,967,295的32位计数器。通过TCP连接交换的数据中每一个字节都经过序列编号。在TCP报头中的序列编号栏包括了TCP分段中第一个字节的序列编号。类似的后续文章介绍中当这个SYN标志位有效的时候我们称呼这个包为SYN包。

FIN(Finish):带有该标志置位的数据包用来结束一个TCP会话,但对应端口仍处于开放状态,准备接收后续数据。当FIN标志有效的时候我们称呼这个包为FIN包。

TCP的三次握手是什么

TCP是面向连接的,在发送数据时无论哪一方发起通信首先必须先建立一条通信的链路,这个建立连接的过程叫做三次握手,三次握手的目的是同步连接双方的初始序列号和确认号,并且协商TCP窗口大小信息,用来进行流量控制。

第一次握手

建立连接。客户端发送请求保温段,将SYN位置为1,Seq为起始编号此时为x,之后客户端状态从CLOSED状态变为SYN_SENT状态

第二次握手

服务器收到SYN报文段,服务器收到科幻的SYN报文段,需要对SYN进行确认设置ACK为X+1(表示我需要的下一包数据为X+1的数据),同时自己还要发送SYN请求,将SYN表示位置1,之后设置自己的Seq为y,之后将这个报文发送给客户端,此时服务端进入SYN_RCVD状态

第三次握手

客户端收到服务器的SYN+ACK报文段,需要对这个报文进行确认,设置ACK 为Y+1(表示我收到了服务端的y号数据包,下一包数据需要的包为Y+1),这个报文完毕之后客户端与服务端都进入ESTABLISHED状态完成TCP三次握手

为什么要三次握手而不是两次或者一次

谢希仁的《计算机网络》中说道:“已失效的连接请求报文段”的产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。”

通俗解释一下就是为了避免因为网络拥堵造成早已发出的TCP连接在延迟一段时间后到达了服务端此时在服务端是不知道这个连接是什么时候来的,所以会发出回复的信息,若这个时候客户端没有再次发送确认的请求的话,server端会认为连接已经建立并且等待数据,这个状态下持续等待一个无效的连接会白白浪费很多资源。用生活来举例子就像是两个人在对话,A对B说我想和你视频,然后B在听到这句话后对A说“嗯,现在可以”,在A收到这句话后会再次对B确认,会对B说:“那我给你发请求了”,假如A没有对B说这句话,B一直在傻等这样岂不是会浪费B很多的时间?如果中间有这句A的回答存在我的B人在一段时间内没收到A的回复就可以认为A不想给B在发送请求了B就可以忙其他事情去了而不用一直在这里傻等。

TCP的四次挥手又是什么

四次挥手是在TCP通讯结束时发送的报文
Client端发起终端连接请求,也就是发送FIN报文,Server端接收到FIN报文意思是对server端说"我这边的报文发送完毕",此时若是还有数据没有发送完成,则不必着急关闭Socket可以继续发送数据,但是在此时我需要回复给客户端"我知道你想要关闭连接了,但我这边还没有准备好,稍微等下我,我搞定了之后会通知你"这个时候client会进入到FIN_WAIT状态继续等待Server端的FIN报文,等到Server端确定数据已经收发完成会对Client再次发送FIN报文告诉Client说“好了,我这边数据发送完成,可以关闭连接了”Client在接收到报文后确认了可以关闭连接,但是因为网络传输的不可靠性所以这个时候client端会再次给server端发送回复消息,当server端确认到了client收到了他之前发送的那条指令后就可以放心的关闭连接了,client端等到2MSL后依然没有收到回复则说明了Server已经正常关闭,这个时候client端也会关闭连接,client端的关闭会有2MSL的时间做等待,这个等待时间是为了确保server端接收到了client端发送的最后一条消息,若在一定时间内server没有接收到客户端发送的最后一条消息会重发fin包,若在2MSL的等待时间中没有接收到重发消息可以确保server端接收到了最后一条消息。在TIME_WAIT状态时两端的端口不能使用,要等到2MSL时间结束才可继续使用。当连接处于2MSL等待阶段时任何迟到的报文段都将被丢弃。不过在实际应用中可以通过设置SO_REUSEADDR选项达到不必等待2MSL时间结束再使用此端口。

TCP的十一种状态

  1. CLOSED状态:初始状态,表示TCP连接是“关闭的”或者“未打开的”。
  2. LISTEN状态:表示服务端的某个端口正处于监听状态,正在等待客户端连接的到来。
  3. SYN_SENT状态:当客户端发送SYN请求建立连接之后,客户端处于SYN_SENT状态,等待服务器发送SYN+ACK。
  4. SYN_RCVD状态:当服务器收到来自客户端的连接请求SYN之后,服务器处于SYN_RCVD状态,在接收到SYN请求之后会向客户端回复一个SYN+ACK的确认报文。
  5. ESTABLISED状态:当客户端回复服务器一个ACK和服务器收到该ACK(TCP最后一次握手)之后,服务器和客户端都处于该状态,表示TCP连接已经成功建立。
  6. FIN_WAIT_1状态:当数据传输期间当客户端想断开连接,向服务器发送了一个FIN之后,客户端处于该状态。
  7. FIN_WAIT_2状态:当客户端收到服务器发送的连接断开确认ACK之后,客户端处于该状态。
  8. CLOSE_WAIT状态:当服务器发送连接断开确认ACK之后但是还没有发送自己的FIN之前的这段时间,服务器处于该状态。
  9. TIME_WAIT状态:当客户端收到了服务器发送的FIN并且发送了自己的ACK之后,客户端处于该状态。
  10. LAST_ACK状态:表示被动关闭的一方(比如服务器)在发送FIN之后,等待对方的ACK报文时,就处于该状态。
  11. CLOSING状态:连接断开期间,一般是客户端发送一个FIN,然后服务器回复一个ACK,然后服务器发送完数据后再回复一个FIN,当客户端和服务器同时接受到FIN时,客户端和服务器处于CLOSING状态,也就是此时双方都正在关闭同一个连接。

TCP连接过程中Client端所经历的状态

在这里插入图片描述

TCP连接过程中Server端所经历的状态

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值