《UNIX网络编程卷1:套接字联网API》第2章 传输层:TCP、UDP和SCTP
《UNIX网络编程卷1:套接字联网API》第2章 传输层:TCP、UDP和SCTP
2.1 传输层的核心作用与协议选型
传输层是网络协议栈中承上启下的核心层,直接决定应用的通信质量。其主要职责包括:
- 端到端通信:屏蔽底层网络细节,为应用提供逻辑通信通道;
- 可靠性保障(TCP/SCTP):通过确认、重传、拥塞控制等机制确保数据完整;
- 多路复用与分用:通过端口号区分不同应用进程;
- 流量控制:防止发送方压垮接收方缓冲区。
协议选型黄金法则:
- TCP:需要可靠传输、数据顺序性的场景(如文件传输、HTTP);
- UDP:低延迟、容忍丢包、强调实时性的场景(如视频会议、DNS查询);
- SCTP:多宿主容灾、多流并发、消息边界保留的场景(如5G核心网信令)。
2.2 TCP协议深度解析
2.2.1 TCP头部结构与字段详解
TCP头部由20字节固定部分和可变选项组成,其结构如下(图2-1):
0 1 2 30 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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Port | Destination Port |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Sequence Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Acknowledgment Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Data | |U|A|P|R|S|F| |
| Offset| Reserved |R|C|S|S|Y|I| Window |
| | |G|K|H|T|N|N| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Checksum | Urgent Pointer |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options (可变长度) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
关键字段解析:
- 序列号(Sequence Number):32位,标识数据段的第一个字节的编号;
- 确认号(Acknowledgment Number):32位,期望收到的下一个字节的编号;
- 窗口大小(Window):16位,接收方的可用缓冲区大小(流量控制核心);
- 标志位:
SYN:发起连接;ACK:确认数据;FIN:关闭连接;RST:强制重置连接;URG:紧急指针有效。
2.2.2 TCP连接管理:三次握手与四次挥手
-
三次握手建立连接(图2-2):
客户端 服务器|-------- SYN(seq=100) ------->||<-- SYN+ACK(seq=300, ack=101)--||-------- ACK(ack=301) -------->|- 序列号随机化:防止历史报文干扰(RFC 6528);
- 半连接队列:服务器在SYN_RCVD状态维护未完成握手队列。
-
四次挥手终止连接(图2-3):
主动关闭方 被动关闭方|-------- FIN(seq=200) ------->||<-------- ACK(ack=201)--------||<-------- FIN(seq=500)--------||-------- ACK(ack=501) ------->|- TIME_WAIT状态:主动关闭方等待2MSL(最大报文段生存时间),防止旧报文干扰新连接;
- 孤儿连接:被动关闭方在CLOSE_WAIT状态需及时关闭。
代码示例:TCP服务器监听连接
int listenfd = Socket(AF_INET, SOCK_STREAM, 0);struct sockaddr_in servaddr;
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(9999);Bind(listenfd, (SA*)&servaddr, sizeof(servaddr));
Listen(listenfd, LISTENQ); // LISTENQ通常设置为SOMAXCONN
2.2.3 流量控制与拥塞控制
-
流量控制:
- 滑动窗口协议:接收方通过窗口字段通告可用缓冲区大小;
- 零窗口探测:发送方定时发送1字节数据,避免死锁。
-
拥塞控制:
- 慢启动(Slow Start):窗口指数增长至阈值;
- 拥塞避免(Congestion Avoidance):窗口线性增长;
- 快速重传(Fast Retransmit):收到3个重复ACK立即重传;
- 快速恢复(Fast Recovery):避免窗口重置为1。
内核参数调优(Linux示例):
# 调整接收缓冲区大小
sysctl -w net.ipv4.tcp_rmem='4096 87380 6291456'
# 启用BBR拥塞控制算法
sysctl -w net.ipv4.tcp_congestion_control=bbr
2.3 UDP协议特性与编程实践
2.3.1 UDP头部结构
UDP头部仅8字节(图2-4):
0 7 8 15 16 23 24 31
+--------+--------+--------+--------+
| 源端口 | 目的端口 |
+--------+--------+--------+--------+
| 长度 | 校验和 |
+--------+--------+--------+--------+
| 数据(若有) |
+-----------------------------------+
核心特点:
- 无连接:无需握手,直接发送数据报;
- 无可靠性保证:不重传、不排序、不拥塞控制;
- 数据报边界保留:每个
sendto对应一个完整报文。
2.3.2 UDP编程核心挑战
- 报文丢失处理:需应用层实现超时重传与确认机制;
- 乱序处理:为每个报文添加序列号;
- MTU限制:避免IP分片(通常限制为1472字节,1500-20-8)。
代码示例:UDP时间服务器
int sockfd = Socket(AF_INET, SOCK_DGRAM, 0);struct sockaddr_in servaddr;
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(9999);Bind(sockfd, (SA*)&servaddr, sizeof(servaddr));char buff[MAXLINE];
struct sockaddr_in cliaddr;
socklen_t len = sizeof(cliaddr);for (;;) {int n = Recvfrom(sockfd, buff, MAXLINE, 0, (SA*)&cliaddr, &len);time_t ticks = time(NULL);snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));Sendto(sockfd, buff, strlen(buff), 0, (SA*)&cliaddr, len);
}
2.3.3 UDP的适用场景
- 实时音视频传输(如WebRTC):容忍丢包,但要求低延迟;
- DNS查询:单次请求响应,无连接开销;
- 广播/多播通信:向多个接收者高效发送数据。
2.4 SCTP协议:下一代传输协议
2.4.1 SCTP核心特性
- 多宿主(Multi-homing):一个端点可绑定多个IP地址,提升容灾能力;
- 多流(Multi-streaming):独立的数据流避免队头阻塞;
- 消息边界保留:基于消息而非字节流;
- 四次握手关联建立:抵御SYN洪泛攻击。
2.4.2 SCTP关联建立与关闭
-
四次握手建立关联(图2-5):
客户端 服务器|-------- INIT(随机数A) ------->||<------- INIT-ACK(随机数B)-----||------- COOKIE-ECHO(加密Cookie)>||<------- COOKIE-ACK ------------|- 状态Cookie:服务器不保存状态,防止DDoS攻击。
-
优雅关闭关联:
主动关闭方 被动关闭方|-------- SHUTDOWN -------------->|<------- SHUTDOWN-ACK -----------||<------- SHUTDOWN-COMPLETE ------|
代码示例:SCTP单流服务器
int listenfd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);struct sockaddr_in servaddr;
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(9999);Bind(listenfd, (SA*)&servaddr, sizeof(servaddr));struct sctp_event_subscribe events;
bzero(&events, sizeof(events));
events.sctp_data_io_event = 1; // 启用数据IO事件
Setsockopt(listenfd, IPPROTO_SCTP, SCTP_EVENTS, &events, sizeof(events));Listen(listenfd, LISTENQ);
2.5 协议对比与选型指南
| 特性 | TCP | UDP | SCTP |
|---|---|---|---|
| 连接方式 | 面向连接 | 无连接 | 面向关联 |
| 可靠性 | 可靠 | 不可靠 | 可靠 |
| 数据边界 | 无 | 有 | 有 |
| 传输模式 | 字节流 | 数据报 | 消息流 |
| 多路径支持 | 否 | 否 | 是(多宿主) |
| 典型应用 | HTTP、FTP、SSH | DNS、QUIC、实时音视频 | 5G信令、VoLTE |
选型建议:
- 嵌入式设备:优先UDP(资源占用低),复杂场景用TCP;
- 高可用服务:SCTP多宿主特性提升容灾能力;
- 实时系统:UDP+应用层协议(如RTSP)。
2.6 实战:多协议时间服务器
2.6.1 TCP时间服务器
(代码参考第1章示例)
2.6.2 UDP时间服务器
#include "unp.h"
#include <time.h>int main() {int sockfd = Socket(AF_INET, SOCK_DGRAM, 0);struct sockaddr_in servaddr;bzero(&servaddr, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = htonl(INADDR_ANY);servaddr.sin_port = htons(9999);Bind(sockfd, (SA*)&servaddr, sizeof(servaddr));char buff[MAXLINE];struct sockaddr_in cliaddr;socklen_t len;for (;;) {len = sizeof(cliaddr);Recvfrom(sockfd, buff, MAXLINE, 0, (SA*)&cliaddr, &len);time_t ticks = time(NULL);snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));Sendto(sockfd, buff, strlen(buff), 0, (SA*)&cliaddr, len);}
}
2.6.3 SCTP时间服务器
#include "unp.h"
#include <netinet/sctp.h>
#include <time.h>int main() {int sockfd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);struct sockaddr_in servaddr;bzero(&servaddr, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = htonl(INADDR_ANY);servaddr.sin_port = htons(9999);Bind(sockfd, (SA*)&servaddr, sizeof(servaddr));struct sctp_event_subscribe events;bzero(&events, sizeof(events));events.sctp_data_io_event = 1;Setsockopt(sockfd, IPPROTO_SCTP, SCTP_EVENTS, &events, sizeof(events));Listen(sockfd, LISTENQ);struct sockaddr_in cliaddr;char buff[MAXLINE];for (;;) {socklen_t len = sizeof(cliaddr);int connfd = Accept(sockfd, (SA*)&cliaddr, &len);time_t ticks = time(NULL);snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));Write(connfd, buff, strlen(buff));Close(connfd);}
}
2.7 调试工具与性能分析
2.7.1 Wireshark抓包分析
- TCP流追踪:右键报文 → Follow → TCP Stream;
- UDP过滤:
udp.port == 9999; - SCTP关联分析:
sctp.association_id。
2.7.2 网络性能测试
- TCP吞吐量测试:
# 服务器端 iperf3 -s # 客户端 iperf3 -c 192.168.1.100 -t 30 - UDP丢包率测试:
iperf3 -u -c 192.168.1.100 -b 100M -t 20
2.8 本章小结与进阶习题
小结:本章深入解析了TCP、UDP、SCTP的协议机制与编程实践,通过对比分析指导协议选型,为复杂网络应用开发奠定基础。
习题:
- 实现SCTP多流客户端,验证不同流的独立性;
- 使用UDP实现可靠文件传输协议(含ACK与超时重传);
- 分析TCP BBR与CUBIC拥塞控制算法的差异,编写测试报告。
付费用户专属资源:
- 完整多协议时间服务器代码工程;
- Wireshark抓包文件(标注关键字段);
- 扩展阅读:《SCTP在5G核心网中的实践》。
通过本章学习,读者将掌握传输层协议的核心原理,并能够根据场景需求选择最佳协议,设计高效可靠的网络应用。
相关文章:
《UNIX网络编程卷1:套接字联网API》第2章 传输层:TCP、UDP和SCTP
《UNIX网络编程卷1:套接字联网API》第2章 传输层:TCP、UDP和SCTP 2.1 传输层的核心作用与协议选型 传输层是网络协议栈中承上启下的核心层,直接决定应用的通信质量。其主要职责包括: 端到端通信:屏蔽底层网络细节&am…...
阿里云平台服务器操作以及发布静态项目
目录: 1、云服务器介绍2、云服务器界面3、发布静态项目1、启动nginx2、ngixn访问3、外网访问测试4、拷贝静态资源到nginx目录下并重启nginx 1、云服务器介绍 2、云服务器界面 实例详情:里面主要显示云服务的内外网地址以及一些启动/停止的操作。监控&…...
【大模型实战篇】使用GPTQ量化QwQ-32B微调后的推理模型
1. 量化背景 之所以做量化,就是希望在现有的硬件条件下,提升性能。量化能将模型权重从高精度(如FP32)转换为低精度(如INT8/FP16),内存占用可减少50%~75%。低精度运算(如INT8…...
Spring WebFlux之流式输出
🎉🎉🎉🎉🎉🎉 欢迎访问的个人博客:https://swzbk.site/,加好友,拉你入福利群 🎉🎉🎉🎉🎉🎉 流式输…...
基于springboot医疗平台系统(源码+lw+部署文档+讲解),源码可白嫖!
摘要 信息化时代,各行各业都以网络为基础飞速发展,而医疗服务行业的发展却进展缓慢,传统的医疗服务行业已经逐渐不满足民众的需求,有些还在以线下预约挂号的方式接待病人,为此设计一个医疗平台系统很有必要。此类系统…...
Stable Diffusion lora训练(一)
一、不同维度的LoRA训练步数建议 2D风格训练 数据规模:建议20-50张高质量图片(分辨率≥10241024),覆盖多角度、多表情的平面风格。步数范围:总步数控制在1000-2000步,公式为 总步数 Repeat Image Epoch …...
网络空间安全(37)获取webshell方法总结
一、直接上传获取Webshell 这是最常见且直接的方法,利用网站对上传文件的过滤不严或存在漏洞,直接上传Webshell文件。 常见场景: 许多PHP和JSP程序存在此类漏洞。例如,一些论坛系统允许用户上传头像或心情图标,攻击者可…...
第十三次CCF-CSP认证(含C++源码)
第十三次CCF-CSP认证 跳一跳满分题解 碰撞的小球满分题解遇到的问题 棋局评估满分题解 跳一跳 题目链接 满分题解 没什么好说的 基本思路就是如何用代码翻译题目所给的一些限制,以及变量应该如何更新,没像往常一样给一个n,怎么读入数据&…...
【Agent】OpenManus-Prompt组件详细分析
1. 提示词架构概述 OpenManus 的提示词组件采用了模块化设计,为不同类型的智能体提供专门的提示词模板。每个提示词模块通常包含两种核心提示词:系统提示词(System Prompt)和下一步提示词(Next Step Prompt࿰…...
swagger ui 界面清除登录信息的办法
我们在开发过程中,用swagger ui 测试接口的时候,可能会要修改当前登录的用户。 但是如果我们在谷歌中对调试的本地swagger ui 登录地址存储过账户密码,每次启动项目调试之后,都会自动登录swagger ui ,登录界面一闪就…...
TensorFlow 的基本概念和使用场景
TensorFlow 是一个由 Google 开发的开源机器学习框架,主要用于构建和训练深度学习模型。下面是一些 TensorFlow 的基本概念和使用场景: 基本概念: 张量(Tensor):在 TensorFlow 中,数据以张量的…...
基于x11vnc的ubuntu远程桌面
1、安装VNC服务 sudo apt install x11vnc -y2、创建连接密码 sudo x11vnc -storepasswd3、安装lightdm服务 x11vnc 在 默认的 GDM3 中不起作用,因此需要使用 lightdm 桌面管理环境 sudo apt install lightdm -y切换至lightdm,上一步已经切换则跳过该…...
Cursor解锁Claude Max,助力AI编程新突破!
Cursor 最新推出的 Claude Max 模型,以其卓越的性能和创新的能力,正在重新定义我们对 AI 辅助编程的认知。这款搭载 Claude3.7 大脑的超级模型,不仅具备超强智能,还凭借一系列技术突破,向传统 AI 编程工具发起了挑战。…...
created在vue3 script setup中的写法
在 Vue 2 里,created 是一个生命周期钩子函数,会在实例已经创建完成之后被调用,主要用于在实例初始化之后、数据观测和 event/watcher 事件配置之前执行代码。而在 Vue 3 的 <script setup> 语法糖里,不再有像 Vue 2 那样直…...
GenICam标准
GenICam的目标是为所有类型的相机提供一个统一的编程接口。无论相机使用的是哪种传输协议或实现了哪些功能,编程接口(API)都是一样的。 GenICam(Generic Interface for Cameras)是一个为工业相机和图像采集设备设计的…...
ESP8266 与 ARM7 接口-LPC2148 创建 Web 服务器以控制 LED
ESP8266 与 ARM7 接口-LPC2148 创建 Web 服务器以控制 LED ESP8266 Wi-Fi 收发器提供了一种将微控制器连接到网络的方法。它被广泛用于物联网项目,因为它便宜、体积小且易于使用。 在本教程中,我们将 ESP8266 Wi-Fi 模块与 ARM7-LPC2148 微控制器连接,并创建一个 Web 服务…...
智享三代 AI 无人直播系统:颠覆传统,重塑直播新格局
在当今数字化浪潮席卷全球的时代,直播行业作为互联网经济的重要组成部分,正以前所未有的速度蓬勃发展。从最初的娱乐直播兴起,到如今电商直播、知识付费直播等多元业态百花齐放,直播已然成为人们生活和商业活动中不可或缺的一环。…...
通过C#脚本更改材质球的参数
// 设置贴图Texture mTexture Resources.Load("myTexture", typeof(Texture )) as Texture;material.SetTexture("_MainTex", mTexture );// 设置整数material.SetInt("_Int", 1);// 设置浮点material.SetFloat("_Float", 0.1f);// 设…...
FPGA管脚约束
目录 前言 一、IO约束 二、延迟约束 前言 IO约束包括管脚约束和延迟约束。 一、IO约束 对管脚进行约束,对应的约束语句: set_property -dict {PACKAGE_PIN AJ16 IOSTANDARD LVCMOS18} [get_ports "led[0]" ] 上面是单端的管脚&…...
已在此计算机上安装相同或更高版本的 .NET Framework 4”安装报错问题
安裝低版本的 .netFramework會被拒絕 需要做兩件事 1,允許windows安裝低版本的.net framework “已在此计算机上安装相同或更高版本的 .NET Framework 4”安装报错问题-CSDN博客 2,設置完成後重新安裝低版本的 .net framework,要用對應開發版本的 Win10 电脑安…...
如何判断 MSF 的 Payload 是 Staged 还是 Stageless(含 Meterpreter 与普通 Shell 对比)
在渗透测试领域,Metasploit Framework(MSF)的 msfvenom 工具是生成 Payload(载荷)的核心利器。然而,当我们选择 Payload 时,经常会遇到一个问题:这个 Payload 是 Staged(…...
【万字总结】前端全方位性能优化指南(一)——Brotli压缩、CDN智能分发、资源合并
前言 2025年前端技术前沿呈现三大核心趋势:AI深度赋能开发全流程,智能工具如GitHub Copilot X和Cursor实现代码生成、实时协作与自动化审查,开发效率提升3倍以上;性能与架构革新,WebAssembly 2.0支持多线程与Rust内存优化,边缘计算将渲染延迟压至50ms内,微前端Module …...
二.使用ffmpeg对原始音频数据重采样并进行AAC编码
重采样:将音频三元组【采样率 采样格式 通道数】之中的任何一个或者多个值改变。 一.为什么要进行重采样? 1.原始音频数据和编码器的数据格式不一致 2.播放器要求的和获取的数据不一致 3.方便运算 二.本次编码流程 1.了解自己本机麦克风参数&#x…...
实现前端.ttf字体包的压缩
前言 平常字体包都有1M的大小,所以网络请求耗时会比较长,所以对字体包的压缩也是前端优化的一个点。但是前端如果想要特点字符打包成字体包,网上查阅资料后,都是把前端代码里面的字符获取,但是对于动态的内容…...
uni-app集成保利威直播、点播SDK经验FQ(二)|小程序直播/APP直播开发适用
通过uniapp集成保利威直播、点播SDK来开发小程序/APP的视频直播能力,在实际开发中可能会遇到的疑问和解决方案,下篇。更多疑问请咨询19924784795。 1.ios不能后台挂起uniapp插件 ios端使用后台音频播放和画中画功能,没有在 manifest.json 进…...
Spring Framework 中 BeanDefinition 是什么
BeanDefinition 是 Spring Framework 中一个核心的接口,它描述了一个 Bean 的定义。你可以把它看作是 Spring IoC 容器中 Bean 的“蓝图”或“配置元数据”。它包含了 Spring 容器创建、配置和管理 Bean 所需的所有信息。 BeanDefinition 中包含的信息:…...
Sensodrive机器人力控关节模组SensoJoint在海洋垃圾清理机器人中的拓展应用
海洋污染已成为全球性的环境挑战,其中海底垃圾的清理尤为困难。据研究,海洋中约有2600万至6600万吨垃圾,超过90%沉积在海底。传统上,潜水员收集海底垃圾不仅成本高昂,而且充满风险。为解决这一问题,欧盟资助…...
MyBatis 配置文件解析使用了哪些设计模式
MyBatis 配置文件解析过程中,主要运用了以下几种设计模式 1. 建造者模式 (Builder Pattern): 应用场景: SqlSessionFactoryBuilder 和 XMLConfigBuilder 类都体现了建造者模式。模式描述: 建造者模式将一个复杂对象的构建过程与其表示分离,使得同样的构…...
sentinel限流算法
限流算法:固定窗口算法、滑动时间窗口、令牌桶和漏桶这四种常见限流算法的原理: 限流算法原理 固定窗口: 固定窗口算法将时间划分为固定大小的窗口,并在每个窗口内限制请求的数量。在每个窗口开始时,计数器重置&#…...
Git的基本指令
一、回滚 1.git init 在项目文件夹中打开bash生成一个.git的子目录,产生一个仓库 2.git status 查看当前目录下的所有文件的状态 3.git add . 将该目录下的所有文件提交到暂存区 4.git add 文件名 将该目录下的指定文件提交到暂存区 5.git commit -m 备注信…...
