TCP IP协议 三次握手与四次挥手

一、TCP 的流量控制

TCP 使用==窗口机制==进行流量控制

什么是窗口?
连接建立时,各端分配一块缓冲区用来存储接收的数据,并将缓冲区的尺寸发送另一端。

接收方发送的确认信息中,包含自己剩余的缓冲区尺寸。

剩余缓冲区空间的数量叫做窗口
TCP 的流控过程(滑动窗口)

TCP的流控过程

二、TCP 格式报文

TCP报文格式

  1. 序号:seq 序号,占 32 位,用来标识从 TCP 源端向目的端发送的字节流,发起方发送数据时对此进行标记。
  2. 确认序号:ack 序号,占 32 位,只有 ACK 标志位为 1 时,确认序号字段才有效,ack = seq + 1。
  3. 标志位:共 6 个,即 URG、ACK、PSH、RST、SYN、FIN 等,具体含义如下:
    • URG(urgent):紧急指针有效
    • ACK(acknowledgement):确认序号有效
    • PSH(push):接收方应该尽快将这个报文交给应用层
    • RST(reset):重置链接
    • SYN(synchronus):发起一个新连接
    • FIN(finish):释放一个链接

注意:
- 不要将确认序号 ack 和标志位中的 ACK 搞混了
- 确认方 ack = 发起方 req + 1,两端配对。


TCP协议中的三次握手和四次挥手图解

TCP (Transmission Control Protocol) 传输控制协议

建立 TCP 需要三次握手才能建立,而断开连接需要四次挥手

3次握手四次挥手

==各状态的意义如下:==

  • LISTEN - 侦听来自远方 TCP 端口的连接请求
  • SYN_SENT - 在发送请求后等待匹配的连接请求
  • SYN_RCVD - 在收到和发送一个连接请求后等待对连接请求的确认
  • ESTABLISHED - 代表一个打开的连接,数据可以传送给用户。
  • FIN_WAIT-1 - 等待远程 TCP 的连接中断请求,或等待先前的中断请求的确认。
  • FIN_WAIT-2 - 从远程 TCP 等待连接中断请求。
  • CLOSE-WAIT - 等待从本地用户发来的连接中断请求
  • CLOSING - 等待远程 TCP 对中断请求的确认
  • TIME-WAIT - 等待足够时间以确保远程 TCP 接收到连接中断请求的确认
  • CLOSED - 没有任何连接状态

三次握手

三次握手

  1. 第一次握手:建立连接时,client 发送 SYN 包(==SYN = 1,seq = j==) 到 server ,并进入 SYN_SEND 状态,等待 server 确认。
  2. 第二次握手:server 收到 SYN 包,由标志位 SYN = 1 知道 client 请求建立连接,server 确认 client 的 SYN,即 server 将设置标志位 ==ACK = 1,以及 ack=j+1==,同时自己也发送一个 SYN 包 (==SYN=1,seq=k==),即 SYN + ACK 包,此时 server 进入 SYN_RCVD 状态。
  3. 第三次握手: client 收到 server 的 SYN+ACK 包,检查 ack 是否为 j+1,ACK 是否为 1 ,如果正确,则向 server 发送确认包 ACK(==ACK=1,ack=k+1==),Server 检查 ack 是否为 k+1,ACK 是否为 1,如果正确,此包发送完毕,client 和 server 进入 ESTABLISHED 状态,完成三次握手。client 与 server 开始传送数据。

==确认号 ack :其数值等于发送方的发送序号 (seq) + 1 (即接收方期待接收的下一个序列号)==

三次握手例子


四次挥手

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

客户端或服务器均可主动发起挥手动作,在 socket 编程中,任何一方执行 close() 操作即可产生挥手操作。

四次挥手
1. 第一次挥手:Client 发送一个 FIN ==(fin = a,ack = b,ACK=1,FIN = 1)==,用来关闭 Client 到 Server 的数据传送,Client 进入 FIN_WAIT_1 状态。
2. 第二次挥手:Server 收到 FIN 后,发送一个 ACK 给 Client ,确认序号 ack 为 收到序号 + 1 (与 SYN 相同,一个 FIN 占用一个序号)即 ==ack = a+1,ACK = 1== ,Server 进入 CLOSE_WAIT 状态。(服务器读通道关闭) (客户端关闭写通道)
3. 第三次挥手: Server 发送一个 FIN (==fin = c,ack = a+1,ACK = 1,FIN = 1==),用来关闭 Server 到 Client 的数据传送,Server 进入 LAST_ACK 状态。
4. 第四次挥手: Client 收到 FIN 后,Client 进入 TIME_WAIT 状态,(客户端关闭读通道) 接着发送一个 ACK (==ack = c+1 ,ACK = 1==)给 Server ,确认序号为收到序号+1 。(服务端关闭写通道)

假设 Client 端发起中断连接请求,也就是发送 FIN 报文,Server 端接收到 FIN 报文,意思是 Client 对 Server 说 “我 Client 端没有数据要发给你了”,但是此时如果 Server 还有数据没有发送完成,则不必急着关闭 Socket ,可以继续发送数据。所以 Server 端先发送 ACK ,告诉 Client 端,“你的请求我收到了,但是我还没准备好,请你继续等我的消息”,此时 Client 端就进入 FIN_WAIT 状态,继续等待 Server 端的 FIN 报文。当 Server 端确定数据已经发送完成,则向 Client 端发送 FIN 报文,告诉 Client 端 ,“好了,我这边的数据发完了,准备好关闭连接了”。Client 端收到 FIN 报文后,就可以关闭连接了,但他还是不相信网络,怕 Server 端不知道要关闭,所以发送 ACK 后进入 TIME_WAIT 状态,如果 Server 端没有收到 ACK,则可以重传。Server 端收到 ACK 后,就知道可以断开连接了,Client 端等待了 2MSL 后依然没有回复,则证明 Server 端已正常关闭,那么 Client 端就可以关闭连接了。此时,TCP 连接就关闭了。

四次挥手实例
==简单来说是“先关读,再关写”==
以客户端发出关闭连接为例
1. 服务器读通道关闭
2. 客户端写通道关闭
3. 客户端读通道关闭
4. 服务器写通道关闭

关闭行为是发起方数据发送完毕后,给对方发送一个 FIN(finish)数据段,直到接收到对方发送的 FIN ,且对方收到了接收确认 ACK 之后,双方的数据通信才完全结束。过程中每次接收都需要返回确认数据段 ACK。

第一阶段 客户机发送完数据之后,向服务器发送一个 FIN 数据段,序列号为 i
1. 服务器收到 FIN(i) 后,返回确认段 ACK,序列号为 i+1,==关闭服务器读通道==;
2. 客户端收到 ACK(i+1) 后,==关闭客户端写通道==。
(此时,客户端仍能通过读通道读取服务器的数据,服务器仍能通过写通道写数据)

第二阶段 服务器发送完数据之后,向客户端发送一个 FIN 数据段,序列号为 j ;
3. 客户端收到 FIN(j) 后,返回确认段 ACK,序列号为 j+1 ,==关闭客户端读通道==;
4. 服务器收到 ACK(j+1) 后,==关闭服务器写通道==

这是标准的TCP关闭两个阶段,服务器和客户机都可以发起关闭,完全对称。

为什么连接的时候是三次握手,关闭却要四次挥手呢?

因为当 Server 收到 Client 端的 SYN 连接请求报文后,可以直接发送 SYN+ACK 报文。其中 ACK 报文用来应答,SYN 报文是用来同步的。但是关闭连接时,当 Server 端接收到 FIN 报文时,很有可能并不会立即关闭 Socket ,所以只能先回复一个 ACK 报文,告诉 Client 端,“你发的 FIN 报文 我已经收到了,只有等到我的 Server 端所有的报文都发送完了,我才能发送 FIN 报文”,因此不能一起发送。所以需要四次握手。

为什么 TIME_WAIT 状态需要经过 2MSL (最大报文段生存时间) 才返回到 CLOSED 状态。

有两个原因:
1. 保证 TCP 协议的全双工连接能够可靠关闭
2. 保证这次连接的重复数据段从网络中消失

解释第一个原因:

如果 Client 直接 CLOSED,那么由于 IP 协议的不可靠性或者其他网络原因,导致 Server 没有收到 Client 最后回复的 ACK,那么 Server 就会在超时之后继续发送 FIN,此时由于 Client 已经 CLOSED 了,就找不到与重发的 FIN 对应的连接,最后 Server 收到 RST 而不是 ACK,Server 就会以为是连接错误把问题报告给高层。这种情况虽然不会造成数据丢失,但是却导致 TCP 协议不符合可靠连接的要求。所以 Client 不是直接进入 CLOSED,而是要保持 TIME_WAIT,当再次收到 FIN 的时候,能够保证对方收到 ACK,最后正确地关闭连接。

解释第二个原因:

如果 Client 直接 CLOSED,然后又向 Server 发起一个新连接,我们不能保证这个新连接与刚关闭连接的端口是不同的,也就是说有可能新连接和老连接的端口号是相同的。一般来说不会发生什么问题,但是还是有特殊情况出现:假设新连接和已经关闭的老连接端口号是一样的,如果前一次连接的某些数据仍然滞留在网络中,这些延迟数据在建立新连接之后才会到达 Server ,由于新连接和老连接的段口是一样的,又因为 TCP 协议判断不同连接的依据是 socket pair ,于是,TCP 协议就认为那个延迟的数据是属于新连接的,这样就和真正的新连接的数据包发生混淆了,所以 TCP 连接还要在 TIME_WAIT状态等待 2倍 MSL,这样可以保证本次连接的所有数据都从网络中消失。

(按道理,四个报文都发送完毕,我们就可以进入 CLOSED 状态了,但是我们必须假象网络是不可靠的,有可能最后一个 ACK 丢失,所以,TIME_WAIT 状态就是用来重发可能丢失的 ACK 报文。)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
水资源是人类社会的宝贵财富,在生活、工农业生产中是不可缺少的。随着世界人口的增长及工农业生产的发展,需水量也在日益增长,水已经变得比以往任何时候都要珍贵。但是,由于人类的生产和生活,导致水体的污染,水质恶化,使有限的水资源更加紧张。长期以来,油类物质(石油类物质和动植物油)一直是水和土壤中的重要污染源。它不仅对人的身体健康带来极大危害,而且使水质恶化,严重破坏水体生态平衡。因此各国都加强了油类物质对水体和土壤的污染的治理。对于水中油含量的检测,我国处于落后阶段,与国际先进水平存在差距,所以难以满足当今技术水平的要求。为了取得具有代表性的正确数据,使分析数据具有与现代测试技术水平相应的准确性和先进性,不断提高分析成果的可比性和应用效果,检测的方法和仪器是非常重要的。只有保证了这两方面才能保证快速和准确地测量出水中油类污染物含量,以达到保护和治理水污染的目的。开展水中油污染检测方法、技术和检测设备的研究,是提高水污染检测的一条重要措施。通过本课题的研究,探索出一套适合我国国情的水质污染现场检测技术和检测设备,具有广泛的应用前景和科学研究价值。 本课题针对我国水体的油污染,探索一套检测油污染的可行方案和方法,利用非分散红外光度法技术,开发研制具有自主知识产权的适合国情的适于野外便携式的测油仪。利用此仪器,可以检测出被测水样中亚甲基、甲基物质和动植物油脂的污染物含量,为我国众多的环境检测站点监测水体的油污染状况提供依据。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值