C语言核心概念复习——TCP/IP协议栈

TCP/IP协议栈详细解析

一、TCP头部结构详解

TCP头部格式(20字节基本头部 + 最多40字节选项)

text

复制代码
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          16位源端口          |         16位目的端口          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       32位序列号                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       32位确认号                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 数据 |  保留 | U | A | P | R | S | F |    16位窗口大小      |
| 偏移 |       | R | C | S | S | Y | I |(接收缓冲区剩余大小)|
| 4位  |  6位  | G | K | H | T | N | N |                    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|        16位校验和          |        16位紧急指针           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    可选选项(最多40字节)                  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                            数据                            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

各字段详细说明

1. 端口相关字段
  • 16位源端口(Source Port):发送方应用程序的端口号

  • 16位目的端口(Destination Port):接收方应用程序的端口号

  • 端口范围:0-65535(0-1023为系统保留端口)

2. 序列控制字段
  • 32位序列号(Sequence Number):当前数据包的序号

    • 用于标识数据包的顺序

    • 防止数据包乱序

    • 初始序列号在建立连接时协商

  • 32位确认号(Acknowledgment Number):期望收到的下一个数据包的序号

    • 表示已经成功收到的数据

    • 采用累积确认机制

3. 头部长度和标志位
  • 4位头部长度(Data Offset):TCP头部长度(以4字节为单位)

    • 最小值为5(表示20字节)

    • 最大值为15(表示60字节)

  • 6位保留位(Reserved):保留未使用,必须设为0

4. 6个控制标志位(各占1位)
复制代码
URG ACK PSH RST SYN FIN
 1   1   0   0   1   0   ← 例如:SYN+ACK包
  • URG(Urgent):紧急数据标志

    • 当URG=1时,表示有紧急数据

    • 紧急指针字段有效

  • ACK(Acknowledgment):确认标志

    • 当ACK=1时,确认号字段有效

    • 建立连接后所有数据包ACK都应为1

  • PSH(Push):推送标志

    • 当PSH=1时,要求接收方立即将数据交给应用程序

    • 避免缓冲区延迟

  • RST(Reset):重置连接标志

    • 当RST=1时,表示连接出现严重错误,需要重建连接
  • SYN(Synchronize):同步序列号标志

    • 当SYN=1时,表示请求建立连接

    • 在三次握手的前两个包中使用

  • FIN(Finish):结束连接标志

    • 当FIN=1时,表示发送方数据已发送完毕,请求关闭连接

    • 在四次挥手时使用

5. 流量控制字段
  • 16位窗口大小(Window Size):接收方缓冲区剩余空间

    • 用于流量控制,防止发送方发送过快

    • 实现滑动窗口协议的基础

    • 接收端通过此字段告知发送端还能接收多少数据

6. 校验和紧急指针
  • 16位校验和(Checksum):用于检测头部和数据的错误

    • 覆盖TCP头部、数据和伪头部

    • 接收方通过校验和验证数据完整性

  • 16位紧急指针(Urgent Pointer):紧急数据的偏移量

    • 当URG=1时有效

    • 指向紧急数据的最后一个字节的位置

7. 可选选项
  • 可选选项(Options):最多40字节的额外信息

    • 最大报文段大小(MSS)

    • 窗口扩大因子

    • 时间戳

    • 选择性确认(SACK)

    • 无操作(NOP)等

紧急数据(带外数据)处理

复制代码
// 发送紧急数据(带外数据)
send(conn_fd, buf, sizeof(buf), MSG_OOB);  // MSG_OOB标志表示紧急数据

// 接收紧急数据
recv(conn_fd, buf, sizeof(buf), MSG_OOB);

// 设置socket选项(一次一个紧急数据)
int opt = 1;
setsockopt(sock_fd, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(opt));

TCP缓冲区大小

  • 发送缓冲区:默认约2KB

  • 接收缓冲区:默认约256KB

  • 可以通过setsockopt()函数调整

二、IP头部结构详解

IP头部格式(20字节基本头部 + 最多40字节选项)

复制代码
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 版本 | 头长 |   服务类型   |           总长度               |
| 4位  | 4位  |   TOS 8位   |          16位                |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          标识(16位)         | 标志 |      段偏移           |
|                             | 3位  |        13位          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  生存时间   |   协议      |           头部校验和          |
|  TTL 8位   |   8位      |             16位              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    源IP地址(32位)                      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                  目的IP地址(32位)                      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    可选选项(最多40字节)                  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

各字段详细说明

1. 版本和头部长度
  • 4位版本号(Version):IP协议版本

    • IPv4:值为4

    • IPv6:值为6

  • 4位头部长度(IHL):IP头部长度(以4字节为单位)

    • 最小值为5(表示20字节)

    • 最大值为15(表示60字节)

2. 服务类型和总长度
  • 8位服务类型(TOS,Type of Service):服务质量参数

    • 用于区分不同服务的优先级

    • 包含:优先级、延迟、吞吐量、可靠性、成本

  • 16位总长度(Total Length):IP数据包总长度

    • 包括IP头部和数据部分

    • 最大值为65535字节

    • 受MTU限制

3. 分片相关字段
  • 16位标识(Identification):数据包标识

    • 用于标识属于同一原始数据包的所有分片

    • 发送方为每个数据包分配唯一标识

  • 3位标志(Flags):分片控制标志

    • 第1位:保留,必须为0

    • 第2位:不分片(DF,Don't Fragment)

      • DF=1:不允许分片

      • DF=0:允许分片

    • 第3位:更多分片(MF,More Fragments)

      • MF=1:后面还有分片

      • MF=0:这是最后一个分片或没有分片

  • 13位段偏移(Fragment Offset):分片偏移量

    • 表示当前分片在原数据包中的位置

    • 以8字节为单位

4. 生存时间和协议
  • 8位生存时间(TTL,Time To Live):数据包生存时间

    • 每经过一个路由器减1

    • 当TTL=0时,数据包被丢弃

    • 防止数据包在网络中无限循环

  • 8位协议(Protocol):上层协议类型

    • ICMP:1

    • TCP:6

    • UDP:17

    • 其他协议有相应的编号

  • 16位头部校验和(Header Checksum):IP头部校验和

    • 只校验IP头部

    • 每个路由器都需要重新计算

5. IP地址
  • 32位源IP地址(Source Address):发送方IP地址

  • 32位目的IP地址(Destination Address):接收方IP地址

6. MTU概念
  • MTU(Maximum Transmission Unit):最大传输单元

    • 指数据链路层能传输的最大数据包大小

    • 以太网MTU通常为1500字节

    • 当IP数据包超过MTU时需要分片

三、以太网数据帧格式

以太网帧结构

复制代码
+----------------+----------------+----------------+----------------+----------------+
|   目的MAC地址   |    源MAC地址   |     类型       |      数据      |     CRC校验    |
|   6字节(48位)  |  6字节(48位)  |  2字节(16位) |  46-1500字节  |  4字节(32位)  |
+----------------+----------------+----------------+----------------+----------------+

各字段详细说明

1. MAC地址字段
  • 6字节目的物理地址(Destination MAC Address):接收方的MAC地址

    • 如果目的MAC为FF:FF:FF:FF:FF:FF,表示广播地址

    • 如果目的MAC为01:00:5E:xx:xx:xx,表示组播地址

  • 6字节源物理地址(Source MAC Address):发送方的MAC地址

2. 类型字段
  • 2字节类型(Type/EtherType):上层协议类型

    • 0x0800:IPv4协议

    • 0x0806:ARP协议(地址解析协议)

    • 0x86DD:IPv6协议

    • 0x8035:RARP协议(反向地址解析协议)

3. 数据字段
  • 46-1500字节数据(Data/Payload):有效载荷

    • 最小46字节:如果数据不足46字节需要填充

    • 最大1500字节:受MTU限制

    • 包含IP头部、传输层头部和应用层数据

4. 校验字段
  • 4字节CRC校验(Frame Check Sequence):循环冗余校验

    • 用于检测数据帧在传输过程中是否出错

    • 接收方通过CRC校验验证数据完整性

特殊协议说明

  • ping命令:使用ICMP协议(Internet控制报文协议)

  • ARP协议:用于IP地址到MAC地址的解析

四、TCP服务器/客户端编程模型

TCP服务器编程流程

复制代码
// 1. 创建socket
int sock_fd = socket(AF_INET, SOCK_STREAM, 0);

// 2. 绑定地址
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(8888);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
bind(sock_fd, (struct sockaddr*)&server_addr, sizeof(server_addr));

// 3. 监听连接
listen(sock_fd, 5);  // 5为等待队列长度

// 4. 接受连接
struct sockaddr_in client_addr;
socklen_t addr_len = sizeof(client_addr);
int conn_fd = accept(sock_fd, (struct sockaddr*)&client_addr, &addr_len);

// 5. 发送数据
send(conn_fd, buffer, strlen(buffer), 0);

// 6. 接收数据
recv(conn_fd, buffer, sizeof(buffer), 0);

// 7. 关闭连接
close(conn_fd);
close(sock_fd);

TCP客户端编程流程

复制代码
// 1. 创建socket
int sock_fd = socket(AF_INET, SOCK_STREAM, 0);

// 2. 可以bind(但不建议,系统会自动分配)
// struct sockaddr_in client_addr;
// bind(sock_fd, (struct sockaddr*)&client_addr, sizeof(client_addr));

// 3. 连接服务器
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(8888);
inet_pton(AF_INET, "192.168.1.100", &server_addr.sin_addr);
connect(sock_fd, (struct sockaddr*)&server_addr, sizeof(server_addr));

// 4. 接收数据
recv(sock_fd, buffer, sizeof(buffer), 0);

// 5. 发送数据
send(sock_fd, buffer, strlen(buffer), 0);

// 6. 关闭连接
close(sock_fd);

关键点说明

  1. 服务器必须bind:指定监听端口

  2. 客户端不建议bind:系统会自动分配端口

  3. listen的第二个参数:等待连接队列的最大长度

  4. accept会阻塞:直到有客户端连接

  5. connect会阻塞:直到连接成功或失败

  6. send/recv可能阻塞:取决于socket是否设置为非阻塞模式

相关推荐
安科士andxe6 小时前
深入解析|安科士1.25G CWDM SFP光模块核心技术,破解中长距离传输痛点
服务器·网络·5g
YJlio9 小时前
1.7 通过 Sysinternals Live 在线运行工具:不下载也能用的“云端工具箱”
c语言·网络·python·数码相机·ios·django·iphone
CTRA王大大10 小时前
【网络】FRP实战之frpc全套配置 - fnos飞牛os内网穿透(全网最通俗易懂)
网络
小白同学_C10 小时前
Lab4-Lab: traps && MIT6.1810操作系统工程【持续更新】 _
linux·c/c++·操作系统os
今天只学一颗糖10 小时前
1、《深入理解计算机系统》--计算机系统介绍
linux·笔记·学习·系统架构
儒雅的晴天10 小时前
大模型幻觉问题
运维·服务器
testpassportcn10 小时前
AWS DOP-C02 認證完整解析|AWS DevOps Engineer Professional 考試
网络·学习·改行学it
通信大师11 小时前
深度解析PCC策略计费控制:核心网产品与应用价值
运维·服务器·网络·5g
不做无法实现的梦~11 小时前
ros2实现路径规划---nav2部分
linux·stm32·嵌入式硬件·机器人·自动驾驶
Tony Bai12 小时前
告别 Flaky Tests:Go 官方拟引入 testing/nettest,重塑内存网络测试标准
开发语言·网络·后端·golang·php