Mmear's 😘.

TCP协议三次握手&四次挥手

字数统计: 1.8k阅读时长: 6 min
2019/03/12 Share

TCP协议中的『三次握手』与『四次挥手』

TCP/IP 参考模型

TCP 协议属于著名的TCP/IP 参考模型,被全球范围内的互联网所使用,该模型从上至下分为『应用层』『传输层』『网络层/互联网层』『数据链路层』,相较于它的原型七层 OSI 参考模型少了『表示层』『会话层』以及『物理层』;

TCP (Transport Control Protocol)即传输控制协议是一个可靠的、面向连接的协议,位于 TCP/IP 模型的第二层『传输层』,该层定义了两个端到端的传输协议,设计目标是允许源主机与目标主机上的对等实体进行对话;同样位于该层的还有用户数据报协议(UDP,User Datagram Protocol),该协议是无连接且不可靠的协议,一般用于语音和视频传输;

TCP 报文信息

TCP 的头部报文结构如下:

TCPHEADER
图片来源

  • 『Port』 传输层与网络层的一个相似任务就是寻址,TCP 协议不关心 IP 地址,只关心目标进程的端口号,因此会携带发起通信进程的端口号和目标端口号;

  • 『Sequence Number』即 seq序号,用于表明当前数据包的顺序, 接收方根据这个序号来给接收到的数据包排序,将有序的报文提交给上层;另外要注意的是当有数据需要发送的时候,seq会随该序列号为原点,对自己将要发送的每个字节的数据进行编号,比如当前seq = 10,本次要发送的数据包大小是200字节,那么实际发送的时候会更新seq=210,以便保证传输的数据的顺序;

  • 『Acknowledege Number』,即ACK确认号,用于对传输方 seq 的确认,一般设置为收到的最后一个 seq 或 seq+1,随着下一个数据包捎带发送出去;只有当标志位中的ACK标志位为1时该确认序列号的字段才有效,用来解决网络丢包问题;

  • 『Window』滑动窗口,win 可以理解为缓冲区域的大小,win 值越大,一次能够发送(无需等待 ACK 应答 )的数据包就越大,win 值会随着数据吞吐速率变化而变化;

  • 『控制位』标志位,常见的有 SYN、ACK、FIN、RST 等;表明各种了下一步通信双方应该进行的动作;如 FIN 表明执行断开连接操作,SYN 表示开始连接操作并设置初始 seq 值 等;

建立连接『三次握手』

如图所示,对百度首页进行一次访问,用 wireshark 捕获的 TCP 包中的前三个完整表示了一次 TCP 协议建立连接的流程;

  1. 客户端向服务器发送建立连接请求包,将 SYN 标志位设置为 1,同时设置起始序号 seq=0,并附带滑动窗口大小(win),希望接受的数据包长度(len),能接受的最大包大小(mss);可以简单表示为SYN(seq=0) mss,Maximum Segment Size: 除去头部后,一个网络包所能容纳的 最大 TCP 数据长度

  2. 服务器响应客户端请求,同意建立连接, 也将 SYN 标志位设置为 1、seq 设置为 0,并设置 ack 号为 1(即上一个接受到的 seq+1、以及滑动窗口等信息;表示为[SYN, ACK](seq=0, ack=1)

  3. 客户端收到目标回应,表明可以建立一次连接,并进行最后的回复确认; 同样设置 ack 号为 1,但 seq 号在之前的基础上+1,最后发送的包表示为ACK(seq=1, ack=1)

目的

『三次握手』的流程是为了尽可能确保一次连接的安全性和快捷性,如果不对请求进行回复确认,双方都不清楚对方是否收到自己的请求,数据的传输便会失去保障;而如果不是三次握手,而是四次五次,则建立连接的效率会变得低下,尤其是 HTTP1.0 协议还没有keep-alive请求头的情况下;

而 ack 确认号与 seq 序号的机制保证了传输的有序性,配合缓冲区能够有效地解决网络传输中的丢包问题;

中断连接——『四次挥手』

TCP 协议是全双工协议,双方可以同时收发数据,为了保证数据完整传输,双方都要对中断进行两次确认;中断过程可以由任意一方发起:

  1. 假设服务器方发起中断请求,首先要将控制位中的 FIN 设置为 1,附带最后的数据信息发送给客户端;表示为FIN(seq),进入FIN_WAIT状态;

  2. 客户端收到 FIN=1,向服务器方发送 ack 号 进行确认,进入CLOSE_WAIT状态;并调用应用程序读取剩余的数据 / 准备发送剩余数据;

  3. 当数据读取完毕后,客户端也进入中断连接操作,和第一步一样向服务器发送FIN(seq),进入LAST_WAIT状态;

  4. 一段时间后,服务器就会返回 ack 号进行最后的确认,进入TIME_WAIT状态,经过一段时间(2MSL,最大报文文段生存时间)后停止监听,中断连接过程结束;


图片来源

目的

四次挥手是因为数据传输的不同步,一方已经传送完数据了,但另一方还没有,于是先接受数据并回复,等到剩余数据准备好再发送 FIN,并等待 ACK 确认以保证双方数据都传输完毕;

至于最后的TIME_WAIT状态,是为了防止最后的 ACK 包丢失,导致对方重发 FIN 但无人回应,甚至中断其它正常套接字的情况;经过最大报文文段生存时间后,即认为对方已经收到了;

滑动窗口

最简单的一问一答形式(等到 ACK 回应后,再发送数据)叫做『单工停等协议』,这种同步方式虽然保证了数据传输的有序和完整,但效率实在低下;为了解决这个问题,TCP 协议采用了滑动窗口协议来管理数据发送和 ACK 号的操作。滑动窗口,即不用等待上一个包的 ACK 确认,就直接发送后续的一系列包;

窗口由16位bit所定义,所以接收端的 TCP 窗口能最大提供65535个字节的缓冲,滑动窗口主要就是做限流和缓冲用的;如图,可以看见有三个连续的 ack=518 的包被发送,而 seq 则是不断增大的,说明 A 向 B 连续发送了三个数据包,只要 B 的滑动窗口还有空间,就可以继续连续发送数据包;

B 在接收到突然的数据后可能来不及处理,便会发送对应的连续 ACK ,告知自己滑动窗口的变化, 当 B 处理完缓冲区的数据后,会向 A 发出一个WINDOW_UPDATE包,告知 A 自己的窗口大小已经增大;

当一方的滑动窗口大小接近于 0 时,另一方便会停止发送,直到接收到 WINDOW_UPDATE 包的通知;

参考

TCP 的那些事儿(上)

CATALOG
  1. 1. TCP协议中的『三次握手』与『四次挥手』
    1. 1.1. TCP/IP 参考模型
    2. 1.2. TCP 报文信息
    3. 1.3. 建立连接『三次握手』
      1. 1.3.1. 目的
    4. 1.4. 中断连接——『四次挥手』
      1. 1.4.1. 目的
    5. 1.5. 滑动窗口
    6. 1.6. 参考