【网络编程】TCP协议解读

TCP 传输控制协议

@(Linux)


1.协议格式

16位源端口号 16位目的端口号
32位顺序序号
32位确认序号
4位头部长度 6位标志位 16位窗口大小
16位校验和 16位紧急指针
可选项 数据

- 源端口地址: 16位源端口地址,端口号2字节 16位,传输层只保存端口号,IP地址在网络层;
- 目的端口地址 接收端的端口号
- 顺序序号 面向字节流发送的,每一个字节都有排序,保证了传输的可靠性有序性
- 确认序号 将一段字节流数据都接受了以后,返回下一个数据的序号;即n+1 表示1到n的数据都接受了
- 头部长度 单位是4字节,一般为5表示20字节;4位最大是15,头部最长为60字节
- 标志位 6位标准位,每一位都有特殊含义
- URC :1标准紧急指针有效
- ACK : 1确认号有效
- PSH :提示接受端立刻从接受缓冲区读数据
- RST :用于重新建立链接,称为复位报文段
- SYN : 请求建立链接,称为同步报文段
- FIN : 断开链接,称为**结束报文段
- 窗口大小 确认应答时返回自己接受端滑动窗口的大小
- 校验位 CRC校验,具体怎么实现没了解过
- 紧急指针 指向优先发送的紧急数据
- 选项
- MSS 最大传输报文段长度 一般默认为536字节,在建立链接是传输给对方;
- 偏移量M 16位窗口大小最大为65535字节,不够用时使用M偏移量,向左移动;

2.面向链接

2.1面向字节流

  • 粘包问题: 应用程序是按照数据包收,TCP是按照字节流发送的,有可能数据包在接受时会剩余一些字节,导致下次接受的接受到这些字节流;
  • 解决方法: 定长的包固定大小读取,不定长的包在报头加入长度,在包之间设置分隔符;

2.2三次握手

  • 基本流程
    • C SYN u——-》 S SYN ACK u+1 w ———》 C ACK u+ 1 w+1
    • 窗口大小,MSS大小
  • 为什么是三次
    • 不是二次:防止 已失效的链接请求 再次获取时,创建多余的链接
    • 不是五次:和3次的效果一样,没有什么多余的优点,最少3次就够了;

2.3四次挥手


  • 基本流程
    • 发送者断开连接
      • C FIN x ——-》 S ACK x+1 y ——-》 C
      • C接受到ACK断开了C的发送链接,但还可以接受
    • 接受者断开连接
      • S FIN ACK u x+1 ———-》 C ACK u+1 x+1 ——》 S
      • S收到ACK直接close, C 经过TIME_WAIT 后close
      • 所以断开链接发起者,会进入以恶搞等待时间;
  • TIME_WAIT 设置时间为2MSL 最长报文段寿命
    • 防止客户端发送的ACK能够被服务器端接受
    • 防止已失效的连接请求 不会出现影响下一个新连接;
  • 服务异常断开
    • 进程终止: 服务器断开先发送FIN,服务器进入TIME_WAIT状态
    • 机器关机:同上
    • 机器断电/断网:客户端不知道服务器端断开链接,发送数据时发现链接不在,发送reset;保活定时器:每过一段时间询问对方在不在,最后确认不再释放链接

服务器解决TIME_WAIT 使用setsockopt( )函数
    #include <sys/socket.h>
    int setsockopt(int socket, int level, int option_name, const void *option_value, size_t option_len);
  • socket: 套件字描述符
  • level:设置的级别 SOL_SOCKET 表示套接字级别
  • option_name: 具体要进行的设置选项 SO_REUSEADDR 打开或关闭地址复用功能
  • option_value:要设置的值 1打开, 0关闭;注意类型是指针,要传地址;
  • optlen:值的长度
int opt = 1;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

3.可靠性

3.1确认应答

每次请求/发送都要收到确认应答,不然就超时重传,会保存已发送的分组的副本,确认后才清除。
确认应答ACK,并返回数据n+1序号,表示1-n的数据都已经接受了

3.2超时重传

发出请求后会等待应答,并加载超时计数器,若过来规定的时间还未收到应答,就再次发送请求包;
- 超时时间:比数据往返的平均时间要大,才能确保不二次发送
- 时间算法
- Kam算法: 从第一次重传开始以后,若一直为收到确认应答,每次重传时间为之前的2倍,指数增长;一定次数后判定无法应答,强制关闭链接或进行拥塞控制
- 自适应算法: RTT样本, 太难了自行百度

3.3滑动窗口

  • 基本概念:为了能够同时发送多条数据,提高性能的一种机制;在缓冲区内指定一段范围作为滑动窗口
  • 缓冲区
    • 发送缓存区: 应用程序发送数据给TCP会先放到缓存区里面,发送缓存区与发送窗口的左边是重合的,缓存区里放有已发送未确认数据准备发送的数据
    • 接受缓存区: 应用程序接受数据时从TCP缓存区里读,数据: 尚未到达,准备接受的数据未按序接受的数据
  • 发送窗口:是发送缓存区里的一段范围,三个指针分开数据的种类,并移动 确认范围;
  • 接受窗口:收到连续到达的数据,才会返回确认应答,否则就是未按序应答,会发送前面的那个应答包。
  • 丢包问题
    • 数据已抵达:确认应答丢包,不影响,只有收到后续的应答包就知道已接受;
    • 数据未抵达:请求包丢包,服务器端多次发送n应答包,说明n包丢了,快重传-》连续收到3个n应答包,重发n,成功后会收到一个n+m应答包;
  • 窗口大小
    注意:举例说明

3.4流量控制

  • 16位窗口大小:建立连接时 ACK写入接受窗口大小;
  • 窗口大小为0时:发送探测数据段;

3.5拥塞控制

  • 慢启动 拥塞窗口一开始为1,每次收到确认+1,遇到阀值改为周期性+1,造成拥塞从头开始阀值减半;
  • 阀值 指数 线性 减半
  • 单位 1是MSS = 536

4.提高性能

4.1延时应答

我过会再答应,确保你缓存区数据处理了部分,腾出缓冲区;下次可以发更多的数据。

4.2捎带应答

How are u? ——I’m fine, and u? SYN+ACK

猜你喜欢

转载自blog.csdn.net/qq_32672481/article/details/81782807