TCP介绍

传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。
TCP工资在网络OSI模型的第四层——传输层
IP在第三层——网络层
ARP在第二层——数据链路层
TCP协议是封装在IP数据包中。

应用数据的封装

数据包结构

  • 源端口(16位长)-识别发送连接端口
  • 目的端口(16位长)-识别接收连接端口
  • 序列号(seq,32位长)

    • 如果含有同步化旗标(SYN),则此为最初的序列号;第一个资料比特的序列码为本序列号加一。
    • 如果没有同步化旗标(SYN),则此为第一个资料比特的序列码。
  • 确认号(ack,32位长)—期望收到的数据的开始序列号。也即已经收到的数据的字节长度加1。
  • 资料偏移(4位长)—以4字节为单位计算出的数据段开始地址的偏移值。
  • 保留(3比特长)—须置0
  • 标志符(9比特长)

    • NS—ECN-nonce。ECN显式拥塞通知(Explicit Congestion Notification)是对TCP的扩展,定义于 RFC 3540 (2003)。ECN允许拥塞控制的端对端通知而避免丢包。ECN为一项可选功能,如果底层网络设施支持,则可能被启用ECN的两个端点使用。在ECN成功协商的情况下,ECN感知路由器可以在IP头中设置一个标记来代替丢弃数据包,以标明阻塞即将发生。数据包的接收端回应发送端的表示,降低其传输速率,就如同在往常中检测到包丢失那样。
    • CWR—Congestion Window Reduced,定义于 RFC 3168(2001)。
    • ECE—ECN-Echo有两种意思,取决于SYN标志的值,定义于 RFC 3168(2001)。
    • URG—为1表示高优先级数据包,紧急指针字段有效。
    • ACK—为1表示确认号字段有效
    • PSH—为1表示是带有PUSH标志的数据,指示接收方应该尽快将这个报文段交给应用层而不用等待缓冲区装满。
    • RST—为1表示出现严重差错。可能需要重新创建TCP连接。还可以用于拒绝非法的报文段和拒绝连接请求。
    • SYN—为1表示这是连接请求或是连接接受请求,用于创建连接和使顺序号同步
    • FIN—为1表示发送方没有数据要传输了,要求释放连接。
  • 窗口(WIN,16位长)—表示从确认号开始,本报文的发送方可以接收的字节数,即接收窗口大小。用于流量控制。
  • 校验和(Checksum,16位长)—对整个的TCP报文段,包括TCP头部和TCP数据,以16位字进行计算所得。这是一个强制性的字段。
  • 紧急指针(16位长)—本报文段中的紧急数据的最后一个字节的序号。
  • 选项字段—最多40字节。每个选项的开始是1字节的kind字段,说明选项的类型。

    • 0:选项表结束(1字节)
    • 1:无操作(1字节)用于选项字段之间的字边界对齐。
    • 2:最大报文段长度(4字节,Maximum Segment Size,MSS)通常在创建连接而设置SYN标志的数据包中指明这个选项,指明本端所能接收的最大长度的报文段。通常将MSS设置为(MTU-40)字节,携带TCP报文段的IP数据报的长度就不会超过MTU(MTU最大长度为1518字节,最短为64字节),从而避免本机发生IP分片。只能出现在同步报文段中,否则将被忽略。
    • 3:窗口扩大因子(3字节,wscale),取值0-14。用来把TCP的窗口的值左移的位数,使窗口值乘倍。只能出现在同步报文段中,否则将被忽略。这是因为现在的TCP接收数据缓冲区(接收窗口)的长度通常大于65535字节。
    • 4:sackOK—发送端支持并同意使用SACK选项。
    • 5:SACK实际工作的选项。
    • 8:时间戳(10字节,TCP Timestamps Option,TSopt)
    • 发送端的时间戳(Timestamp Value field,TSval,4字节)
    • 时间戳回显应答(Timestamp Echo Reply field,TSecr,4字节)

      • 19:MD5摘要,将TCP伪首部、校验和为0的TCP首部、TCP数据段、通信双方约定的密钥(可选)计算出MD5摘要值并附加到该选项中,作为类似对TCP报文的签名。通过 RFC 2385 引入,主要用于增强BGP通信的安全性。
      • 29:安全摘要,通过 RFC 5925 引入,将“MD5摘要”的散列方法更换为SHA散列算法。

三次握手

TCP报文里有SYN,ACK和FIN等标识,如何设置1就是开启,如果设置0就是关闭
首先客户端发送TCP报文的时候,会把SYN开启,并且会随机生成一个 序号 作为初始值来进行后续的判断依据
假设初始 序号:8633 当服务器接收到SYN后,服务器会在TCP报文中把SYN和ACK开启,确认同步
服务器也生成自己的序号假设 序号:303,并且加上 确认号:8633+1 ,这个确认号就是对方的序号+1得到的,这样客户端在收到号码后-1就知道是不是自己发送的TCP报文,
最后客户端还需要确认,服务器发送的“确认同步”是否被接收到,客户端就必须再发送一次TCP报文 使连接正式建立,这时客户端会把ACK开启,这里的序号就是用对方的确认好生成,并且再确认号上根据对方的 序号+1
ACK=序号+长度=下一包起始序号

四次挥手

内容传输完成,后各自可能会发起关闭连接的请求,客户端和服务端都可以主动发起关闭请求。
在发送请求和响应的时候序号和确认号会被递增
虽然发送了TCP报文,但此时客户端并不会正式关闭通道,因为服务端可能还有需要发送的数据
服务端发送完数据后会再发送一个FIN+ACK来进行最后的确认,序号和确认号不需要改变,因为没有一来一回,只是多了一个控制位FIN来进行确认结束步骤
最后客户端得到最终的结束确认后会发送ACK来进行确认

结构图

最后修改:2023 年 10 月 26 日
如果觉得我的文章对你有用,请随意赞赏