TCP/IP协议

TCP

概述

TCP/IP协议栈时一系列网络协议的总和,是构成网络通信的核心骨架,定义了电子设备如何连入互联网,以及数据如何在它们之间进行传输。

TCP/IP协议采用4层结构,分别是应用层,传输层,网络层,链路层,物理层,每一层都呼叫它的下一层所提供的协议来完成自己的需求。

简介

TCP是面向连接, 可靠的, 面向流的传输协议.

TCP和UDP都是传输层协议.

传输方式的分类

面向有链接型面向无连接型两类

TCP数据包

应用层发送数据, 首先经过传输层进行包装 添加TCP等信息, 在经过网络层添加IP等信息, 最后链路层进行包装

TCP首部最小20个字节,分为5层, 每层4个字节 即32位.

  • 第一层: 源端口号 + 目标端口号 分别占用16位.

  • 第二层: 32位序列号

    • TCP使用序列号对数据进行标记, 便于到达目的后重新组装.
  • 第三层: 32位确认号

    • 确认号用于表示期望收到对方下一次报文段的序号值
  • 第四层: 4位首部长度 + 6位保留 + 6位标识 + 16位窗口大小

    • 4位表示了TCP的报文段的首部长度, 指出了TCP数据起始处TCP报文起始处的长度
    • 6位用于保留使用
    • 6个标志位, 每个1bit
  • 第五层: 16位校验和 + 16位紧急指针

序列号

序列号占32位, 用于对数据进行标记, 便于到达目的后重新组装

确认号

确认好占32位, 用于表示期望收到对方下一次报文段的序号值

标志位

一共有六个标志位, 每一位1个bit. 分别是: ACK, RST, FIN, SYN, PSH, URG.

  • ACK: 确认序号有效
  • RST: 重置连接
  • SYN: 发起新连接
  • FIN: 释放一个连接
  • URG: 紧急消息
  • PSH: 缓冲区未填满

当TCP连接建立后, 传送的所有报文段的ACK必须设置为1.

PSH=1 表明该报文段高优先级, 不用等待缓冲区填满.

窗口大小

窗口大小位于第4层, 占16位.

主要用于告知对方端: 当前端的TCP缓冲区还能容纳多少数据. 可以控制发送数据的速度.

校验

校验占用两个字节, 16位,位于第五层.

主要用于结合CRC算法校验TCP的报文是否损坏过. 校验范围: 首部+数据

紧急指针

紧急指针占2个字节, 16位当URG=1时才有效.

用于表示当前报文段中紧急数据的大小.

TCP为什么可靠?

因为TCP使用了三次握手才建立了连接.

C代表客户端, S代表服务端

三次握手

C —-> SYN K —-> S

C <—- SYN N + ACK K + 1 <—- S

C —-> ACK N + 1 —-> S

四次握手

客户端主动发起断开操作:

C —-> FIN K —-> S

C <—- ACK K + 1 <—- S : 客户端端和服务端都进入等待状态

C <—- FIN N <—- S : 客户端进入TIME_WAIT, 等待2MSL时间

C —-> ACK N + 1 —-> S :

MSL 表明最长报文段寿命.

等待2MSL?

当C进入TIME_WAIT时, 需要再次向S响应一个ACK报文段, 表明客户端收到了关闭请求.

  1. 保证此次连接的数据段在网络中消失
  2. 保证TCP协议的全双工连接能够可靠关闭

TCP拥塞控制

当网络出现阻塞, 发送的数据会丢失, 此时发送方会重试, 从加重拥塞. 解决此问题一共有四种算法:

慢开始, 拥塞避免, 快重传, 快恢复.

慢开始和拥塞避免

发送方会维护一个发送窗口的状态变量(cwnd).

当建立连接后首次发送数据时进入慢开启 cwnd=1, 当收到确认后 cwnd 开始成倍递增. 随着报文段数量上升, 网络的拥塞的可能性越大, 当cwnd达到一个阈值后(ssthresh 同时进入拥塞避免), 则cwnd将不会成倍增长, 而是+1. 如果超时则cwnd /= 2.

快重传/快恢复

当接受方收到报文后, 主要向发送方发送确认消息, 确认最后一个有序报文段. 如果发送方收到对某个报文段的多次且重复的确认,则会进入快重传, 重新发送丢失的报文段.

而由于报文段丢失, 接受方位收到确认, 则可能重新进入慢开始. 此时则需要执行快恢复. 将cwnd = ssthresh = cwnd / 2.

TCP粘包和拆包

粘包就是连续发送的两个数据包 粘到了一块. 本来接受方需要接受两次的, 发生粘包后一次就可以了.

拆包就是连续发送的两个数据包, 其中一个被拆成了两部分. 例如: packetA 被拆成了 packetA.1 packetA.2 两个.

为什么?

  • 发送的数据小于TCP的缓冲区会发生拆包
  • 发送的数据大于MSS(报文最大长度)会发生拆包
  • 发送的数据小于TCP的缓冲区会发生粘包 或 TCP将多次写入缓冲区的数据一次刷出也会发生粘包
  • 接受方没有及时读取接受缓冲区的中的数据

解决办法

由于TCP是面向流的, 所以从底层是无法解决的. 只能从上层(应用层)解决.

  • 消息定长: 发送的数据包长度一致, 不够的话填充0
  • 设置消息边界: 类似于标识, 例如FTP使用回车换行符来进行数据分割.
  • 消息分割: 将消息分为. 头中会保存消息体的长度.

总结

首先梳理一下每层模型的职责:

  • 链路层:对0和1进行分子,定义数据帧,确认主机的物理地址,传输数据。
  • 网络层:定义IP地址,确认主机所在网络位置,并通过IP进行MAC寻址,对外网数据包进行路由转发。
  • 传输层:定义端口,确认主机上应用程序身份,并将数据包交给对应的应用程序。
  • 应用层:定义数据格式,并按照对应的格式解读数据。

TCP/IP协议
https://chenmc.cn/2023/10/08/tcp/Tcp/
作者
better
发布于
2023年10月8日
许可协议