socket套接字

一、相关函数

sockaddr_in 头文件:#include <netinet/in.h>

结构体原型

cs 复制代码
struct sockaddr_in {
    short            sin_family;    // 协议家族
    unsigned short   sin_port;      // 端口号
    struct in_addr   sin_addr;      // IP地址
    char             sin_zero[8];   // 占位填充,不用管
};

内嵌的 in_addr:

cs 复制代码
struct in_addr {
    in_addr_t s_addr;   // 存IPv4地址,是个32位整数
};

1)sin_family

固定填:AF_INET 意思:使用 IPv4 网络协议

2)sin_port

端口号

  • 范围 1~65535
  • 注意:必须用 网络字节序 ,要用 htons() 转换示例:htons(8080)

3)sin_addr.s_addr

IP 地址

  • 存的是大端网络字节序整数,不是字符串
  • 常用赋值:
    • 本机监听:htonl(INADDR_ANY) 监听本机所有网卡 IP
    • 指定 IP:inet_addr("192.168.1.100")

4)sin_zero8

凑数占位 为了和通用结构体 struct sockaddr 内存大小对齐,直接 memset 清零就行,不用赋值

模板

cs 复制代码
struct sockaddr_in serv_addr;
// 先全部清零
memset(&serv_addr, 0, sizeof(serv_addr));

serv_addr.sin_family = AF_INET;         // IPv4
serv_addr.sin_port   = htons(8080);     // 端口转网络字节序
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); // 监听所有IP

二、TCP(传输控制协议)

TCP(传输控制协议)是一种面向连接的、可靠的传输层协议,其首部包含多个关键字段,用于实现数据的可靠传输、流量控制和拥塞控制等。

我们逐项分析选项:

源端口

→ 用于标识发送方的应用程序端口号,属于通信双方的"身份识别",不涉及数据段顺序

**序号(Sequence Number)**​

用于标识本报文段所携带数据的第一个字节在整个数据流中的位置 ,接收方据此对数据段进行排序重组,确保数据按序交付。这是标识数据段顺序的核心字段

**确认号(Acknowledgment Number)**​

→ 表示期望收到的下一个字节的序号,用于确认机制,不是标识发送方数据段顺序,而是接收方反馈。

D窗口大小

→ 用于流量控制,告诉对方自己还能接收多少数据,与顺序无关


总结记忆口诀

"序号排顺序,确认回位置,端口找应用,窗口控流量。"


三、在 IP 数据报首部中,各字段功能如下:

  • A. 版本号:标识 IP 协议的版本(如 IPv4 或 IPv6),与跳数无关。

  • B. 生存时间 (TTL, Time To Live)核心考点。该字段用于限制数据包在网络中可经过的最大跳数(或生存时间)。每经过一个路由器,TTL 值减 1,当减到 0 时,数据包被丢弃,防止无限循环。因此,它正是"指示数据包可以经过的最大跳数"的字段。

  • C. 协议:指明上层协议类型(如 TCP、UDP、ICMP 等),用于交付给正确协议处理。

  • D. 总长度:表示整个 IP 数据报的总字节数,包括首部与数据部分。


记忆口诀

"TTL 控跳数,过期就丢包;版本看协议,长度算总长。"


四、不同协议对应的协议字段

在 IP 数据报首部中,有一个"协议"字段(Protocol Field),用于标识上层协议的类型,即 IP 层之上封装的是哪种传输层或网络层控制协议。

根据 IANA(互联网号码分配局)定义的标准协议号:

  • 6 → TCP(Transmission Control Protocol)

  • 17 → UDP(User Datagram Protocol)

  • 1 → ICMP(Internet Control Message Protocol)

  • 值为 89 → 表示上层是 OSPF 协议(Open Shortest Path First)

  • HTTP ​ 不是传输层协议,而是应用层协议,不会直接出现在 IP 首部的协议字段中,它通常运行在 TCP 之上(即协议字段为 6)。


关键记忆点:

IP 首部协议字段值:

  • 1:ICMP

  • 6:TCP

  • 17:UDP

  • 89:OSPF


因此,当 IP 首部的协议字段值为 6 时,表示上层协议是 TCP

五、TCP 协议的校验范围


解题思路:

TCP 协议的校验和(Checksum) 字段用于检测传输过程中数据是否出错,其校验范围不仅包括 TCP 首部和 TCP 数据部分,还包括一个伪首部(Pseudo Header)

伪首部不是实际传输的数据,它由 IP 层提供,包含:

  • 源 IP 地址(4 字节)

  • 目的 IP 地址(4 字节)

  • 协议号(1 字节,TCP 为 6)

  • TCP 报文段总长度(2 字节)

加入伪首部的目的是为了增强校验的可靠性,确保数据确实发往正确的目的地,且协议类型无误,防止 IP 层错误转发或损坏。

因此,TCP 校验和计算范围 = 伪首部 + TCP 首部 + TCP 数据

**记忆口诀:**​

"TCP 校验三部分,伪头+首部+数据,缺一不可保准确。"

如需深入理解,可结合 RFC 793 或《计算机网络》(谢希仁)第5版相关内容。

六、IP片偏移量

解题思路:

在 IP 数据报分片机制中,"片偏移"(Fragment Offset)字段用于指示当前分片在原始数据报中的位置,单位不是字节,而是8字节(64位)

原因如下:

  • IP 报头中"片偏移"字段占 13 位。

  • 为了能表示更大的数据报偏移位置,同时节省字段空间,协议设计者将偏移单位定为 8 字节。

  • 也就是说,片偏移值 × 8 = 当前分片数据在原始数据报中从第几个字节开始。

举例:

若片偏移字段值为 100,则表示该分片的数据从原始数据报的第 100 × 8 = 800 字节开始。


记忆口诀

"IP分片偏移量,单位不是1字节,而是8字节记牢它。"

七、服务类型的作用

解题思路:

在IP协议首部中,"服务类型(Type of Service, TOS)"字段(在IPv4中为8位)主要用于指示数据包在传输过程中应享受的服务等级或优先级 ,以实现服务质量(QoS, Quality of Service)控制。该字段可影响路由器在转发数据包时的处理策略,如延迟、吞吐量、可靠性等。

我们逐项分析选项:

  • A 优先级和服务质量控制​ ✅

    正确。TOS字段正是用于指定数据包的优先级和期望的服务质量,如低延迟、高吞吐量或高可靠性等。在现代IP网络中,TOS字段的部分位已被重新定义为"差分服务码点(DSCP)",仍服务于QoS。

  • B 标识协议类型​ ❌

    协议类型由IP首部中的"协议(Protocol)"字段标识,如TCP=6,UDP=17,不是TOS的功能。

  • C 分片控制​ ❌

    分片由"标识(Identification)"、"标志(Flags)"和"片偏移(Fragment Offset)"字段控制,与TOS无关。

  • D 生存时间控制​ ❌

    生存时间(TTL, Time to Live)是IP首部中独立的8位字段,用于防止数据包在网络中无限循环,不属于TOS字段功能。


**小贴士:**​

虽然TOS字段在早期未被广泛使用,但在现代网络中,其演进形式(如DSCP)已成为QoS策略的重要基础,尤其在企业网和多媒体传输中至关重要。

掌握IP首部各字段功能,对网络排错和协议分析非常有帮助!

八、数据偏移的含义

在 TCP 协议首部中,"数据偏移"(Data Offset)字段是一个 4 位长的字段,它表示的是TCP 首部的长度,单位是"4字节"(即 32 位)。

  • 为什么叫"数据偏移"?

    因为它指示了"从 TCP 报文段开头到数据部分开始的位置"有多远,也就是首部占了多少个 4 字节单元。因此,它本质上是在告诉接收方:数据从哪里开始,而这个"偏移量"就是首部长度。

  • 举例:

    如果数据偏移字段值为 5,表示首部长度 = 5 × 4 = 20 字节,这是标准 TCP 首部长度(无选项字段时)。

    若有选项字段,该值会更大(最大为 15,即 60 字节)。


错误选项分析:

  • A. "数据部分的起始位置" ------ 表述不准确,虽然它间接决定了数据起始位置,但该字段的正式含义是首部长度,标准教材和协议文档中均如此定义。

  • C. "窗口大小偏移" ------ 窗口大小是另一个独立字段,无关偏移量。

  • D. "校验和偏移" ------ 校验和也是独立字段,不存在"偏移"说法。


**总结记忆口诀:**​

"数据偏移看首长,单位四字节莫忘;不是数据起始点,而是头部有多长。"


**关键词强化:**​

数据偏移 = 首部长度(以4字节为单位)

此题是计算机网络经典考点,务必掌握。

九、标识的作用

在 IP 数据报首部中,"标识"(Identification)字段是一个 16 位的字段,其核心作用是唯一标识一个 IP 数据报,尤其在数据报被分片时,所有属于同一个原始数据报的分片会携带相同的"标识"值,以便接收端能正确重组。

我们逐项分析选项:

  • A 唯一标识 IP 数据报​ → ✅ 正确。这是标识字段的主要功能。即使分片,所有碎片共享同一标识,用于重组时匹配。它不是"全球唯一",但在同一源主机发送的短时间内可视为唯一。

  • B 标识协议类型​ → ❌ 错误。协议类型由"协议"(Protocol)字段标识,如 TCP=6、UDP=17 等。

  • C 标识分片顺序​ → ❌ 错误。分片顺序由"片偏移"(Fragment Offset)字段标识,不是"标识"字段。

  • D 标识源主机​ → ❌ 错误。源主机由"源 IP 地址"字段标识。


小结记忆口诀:

"标识"辨报不分家,分片重组靠它查;

协议类型看"协议",偏移排序找"片偏移";

源目地址各司职,别把功能搞混啦!


如需进一步理解 IP 首部结构,可重点掌握:版本、首部长度、服务类型、总长度、标识、标志、片偏移、TTL、协议、首部校验和、源/目的 IP 地址等字段功能。

MTU(Maximum Transmission Unit)是链路层最大传输单元,影响的是 IP 数据报在链路层的分片,与 TCP 应用层"消息边界"无关。减小 MTU 可能影响传输效率或引发更多分片,但无法解决"粘包"问题------因为粘包本质是应用层协议设计问题,不是网络层或链路层的问题。

十、TCP首部包含哪些字段

TCP(传输控制协议)首部包含多个关键字段,用于实现可靠传输、流量控制、连接管理等功能。我们逐项分析:

A. 源端口和目的端口

✅ 正确。TCP首部前20字节固定部分就包含"源端口号"(16位)和"目的端口号"(16位),用于标识通信双方的应用进程。

B. 序号和确认号

✅ 正确。"序号"(Sequence Number)用于标识本报文段数据第一个字节的序号;"确认号"(Acknowledgment Number)表示期望收到的下一个字节序号,是TCP可靠传输的核心机制。

C. 窗口大小

✅ 正确。"窗口大小"(Window Size)用于流量控制,指示接收方当前可接收的数据量(以字节为单位)。

D. 生存时间

❌ 错误。"生存时间"(TTL, Time To Live)是IP数据报首部的字段,用于限制数据包在网络中的生存周期,防止无限循环。TCP首部不包含该字段。


**总结:**​

TCP首部关键字段包括:源/目的端口、序号、确认号、数据偏移、标志位、窗口大小、校验和、紧急指针等。

"生存时间"属于IP层,不属于TCP首部。

十一、IP 数据报首部标志位字段

解题思路:

在 IPv4 数据报首部中,"标志(Flags)"字段占 3 位,位于"标识"字段之后、"片偏移"字段之前。这 3 位分别是:

  1. 第1位:保留位(Reserved Bit)

    → 当前未使用,必须置为 0,留作将来扩展。

  2. **第2位:不分片位(DF --- Don't Fragment)**​

    → 若置为 1,表示该数据报不允许分片;若置为 0,允许分片。

  3. **第3位:更多分片位(MF --- More Fragments)**​

    → 若置为 1,表示后面还有分片;若置为 0,表示这是最后一个分片(或未分片)。


错误选项分析:

D. 紧急标志

→ 这是 TCP 协议首部​ 中的标志位(URG 标志),不属于 IP 首部的标志位字段。属于干扰项。


总结:

**IP 首部标志位字段包含:保留位、不分片(DF)、更多分片(MF)**​ ------ 对应选项 A、B、C。

建议记忆口诀:"保不分更" ------ 保留、不分片、更多分片。

十二、粘包本质

解题思路(逐步分析):

第一步:理解"TCP粘包"是什么

TCP粘包是指在使用TCP协议传输数据时,发送方连续发送的多个数据包,在接收方被"粘"在一起,导致接收端无法准确区分每个数据包的边界。这不是TCP协议的错误,而是因为TCP是面向字节流的协议,本身不保留消息边界。


第二步:逐项分析选项

A. TCP 面向字节流

✅ 正确。这是粘包问题的根本原因。TCP把数据看作一串连续的字节流,不关心应用层的消息边界。应用层发送的多个小包可能被合并传输,接收端若不主动分隔,就会"粘"在一起。

B. 发送方缓冲区机制

✅ 正确。TCP协议栈在发送数据时,会先将数据存入发送缓冲区,当缓冲区数据积累到一定程度或达到超时阈值时才会真正发送(Nagle算法或延迟确认机制)。这会导致多个小数据包合并发送,加重粘包现象。

C. 接收方读取不及时

✅ 正确。如果接收方没有及时从接收缓冲区读取数据,后续到来的数据会继续堆积在缓冲区中,接收程序一次读取时可能把多个数据包"一锅端",从而导致粘包。

D. IP 分片重组

❌ 错误。IP分片是网络层行为,发生在数据包过大超过MTU时被拆分,在接收端重组。它影响的是IP数据报的完整性,与TCP"粘包"无关。粘包发生在传输层(TCP),而IP分片属于网络层,二者属于不同层级,不应混为一谈。


**总结关键词:**​

TCP粘包的核心原因 = 面向字节流 + 缓冲区机制 + 接收方读取延迟

IP分片不属于粘包成因。


**附加建议(开发中如何解决粘包?)**​

  • 使用固定长度消息

  • 使用分隔符(如换行符、特殊字符)

  • 在消息头添加长度字段(推荐)

  • 使用应用层协议如 Protobuf、JSON + 长度前缀等

希望这个解析帮你彻底理解粘包问题的本质!

十三、IP 数据报首部中与分片机制直接相关的字段


【解题思路】

IP 数据报在传输过程中,如果遇到 MTU(最大传输单元)限制,需要进行分片(Fragmentation)。为了保证分片后能正确重组,IP 首部设计了几个关键字段用于控制和标识分片:


✅ **A. 标识(Identification)**​

→ 用于标识属于同一个原始数据报的所有分片。同一个数据报的所有分片具有相同的"标识"值,接收端据此判断哪些分片属于同一个报文。

与分片相关,正确


✅ **B. 标志位(Flags)**​

→ 包含 3 位,其中最重要的是"不分片 DF"(Don't Fragment)和"还有分片 MF"(More Fragments)。

→ DF=1 表示禁止分片;MF=1 表示后面还有分片。

控制分片行为,与分片密切相关,正确


✅ **C. 片偏移(Fragment Offset)**​

→ 指明当前分片在原始数据报中的相对位置(以 8 字节为单位)。用于接收端正确重组数据报。

分片重组的关键字段,正确


❌ **D. 总长度(Total Length)**​

→ 表示当前 IP 数据报(包括首部和数据部分)的总字节数。

→ 虽然它会影响是否需要分片(比如超过 MTU 就要分),但它本身不参与分片的控制或重组逻辑,不属于"与分片相关"的核心控制字段。

不是直接用于分片机制的字段,错误


**【正确答案】**​

A. 标识

B. 标志位

C. 片偏移


⚠️ 注意:如果题目为单选题 ,通常会选最核心或最常考的一个,但此处从选项设置和考生勾选情况看,应为多选题 (选项 C、D 被勾选说明是多选)。严格按知识点,A、B、C 均正确


📌 总结记忆口诀:

**"标识定归属,标志控分片,偏移定位置"**​ ------ 对应标识、标志位、片偏移。

如考试中遇到此题,请确认题型是否允许多选,若为多选,则选 ABC ;若为单选,优先选 C 片偏移(最核心重组字段),但多数教材和考试中此题为多选。

在 TCP 首部中,"紧急指针"(Urgent Pointer)字段的作用是标识"紧急数据"的结束位置,但它的有效性依赖于 URG 标志位

  • URG 标志位 = 1(置位)时,表示当前报文段中包含紧急数据,此时"紧急指针"字段才有效,用于指示紧急数据的末尾位置。

  • URG 标志位 = 0 (未置位)时,表示无紧急数据,"紧急指针"字段被忽略,无效

因此,题干中"紧急指针字段在 URG 标志位无效时也有效"的说法是错误的。

相关推荐
Scott9999HH5 小时前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
码智社6 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
AI云海6 小时前
python 列表、元组、集合和字典
开发语言·python
萧瑟余晖7 小时前
JDK 26 新特性详解
java·开发语言
马优晨8 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
人邮异步社区9 小时前
怎么把C语言学到精通?
c语言·开发语言
心平气和量大福大10 小时前
C#-WPF-控件-TextBox 数据绑定
开发语言·c#·wpf
ttwuai10 小时前
Cursor 生成 CRUD 后,Go 后台接口别只测 200:JWT、RBAC 和 tenant_id 怎么验
开发语言·后端·golang
এ慕ོ冬℘゜10 小时前
前端基础:什么是时间戳?JS获取时间戳三种方法与实战用途
开发语言·前端·javascript
执明wa10 小时前
LayoutInflater详解: XML是如何变成View的?
android·xml·开发语言·android studio