《UNIX网络编程卷1:套接字联网API》第2章 传输层:TCP、UDP和SCTP

news2025/3/20 17:46:20

《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                   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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          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连接管理:三次握手与四次挥手
  1. 三次握手建立连接(图2-2):

    客户端                            服务器
      |-------- SYN(seq=100) ------->|
      |<-- SYN+ACK(seq=300, ack=101)--|
      |-------- ACK(ack=301) -------->|
    
    • 序列号随机化:防止历史报文干扰(RFC 6528);
    • 半连接队列:服务器在SYN_RCVD状态维护未完成握手队列。
  2. 四次挥手终止连接(图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. 流量控制

    • 滑动窗口协议:接收方通过窗口字段通告可用缓冲区大小;
    • 零窗口探测:发送方定时发送1字节数据,避免死锁。
  2. 拥塞控制

    • 慢启动(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编程核心挑战
  1. 报文丢失处理:需应用层实现超时重传与确认机制;
  2. 乱序处理:为每个报文添加序列号;
  3. 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关联建立与关闭
  1. 四次握手建立关联(图2-5):

    客户端                            服务器
      |-------- INIT(随机数A) ------->|
      |<------- INIT-ACK(随机数B)-----|
      |------- COOKIE-ECHO(加密Cookie)>|
      |<------- COOKIE-ACK ------------|
    
    • 状态Cookie:服务器不保存状态,防止DDoS攻击。
  2. 优雅关闭关联

    主动关闭方                        被动关闭方
      |-------- 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 协议对比与选型指南
特性TCPUDPSCTP
连接方式面向连接无连接面向关联
可靠性可靠不可靠可靠
数据边界
传输模式字节流数据报消息流
多路径支持是(多宿主)
典型应用HTTP、FTP、SSHDNS、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的协议机制与编程实践,通过对比分析指导协议选型,为复杂网络应用开发奠定基础。

习题

  1. 实现SCTP多流客户端,验证不同流的独立性;
  2. 使用UDP实现可靠文件传输协议(含ACK与超时重传);
  3. 分析TCP BBR与CUBIC拥塞控制算法的差异,编写测试报告。

付费用户专属资源

  • 完整多协议时间服务器代码工程;
  • Wireshark抓包文件(标注关键字段);
  • 扩展阅读:《SCTP在5G核心网中的实践》。

通过本章学习,读者将掌握传输层协议的核心原理,并能够根据场景需求选择最佳协议,设计高效可靠的网络应用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2318506.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

阿里云平台服务器操作以及发布静态项目

目录&#xff1a; 1、云服务器介绍2、云服务器界面3、发布静态项目1、启动nginx2、ngixn访问3、外网访问测试4、拷贝静态资源到nginx目录下并重启nginx 1、云服务器介绍 2、云服务器界面 实例详情&#xff1a;里面主要显示云服务的内外网地址以及一些启动/停止的操作。监控&…

【大模型实战篇】使用GPTQ量化QwQ-32B微调后的推理模型

1. 量化背景 之所以做量化&#xff0c;就是希望在现有的硬件条件下&#xff0c;提升性能。量化能将模型权重从高精度&#xff08;如FP32&#xff09;转换为低精度&#xff08;如INT8/FP16&#xff09;&#xff0c;内存占用可减少50%~75%。低精度运算&#xff08;如INT8&#xf…

基于springboot医疗平台系统(源码+lw+部署文档+讲解),源码可白嫖!

摘要 信息化时代&#xff0c;各行各业都以网络为基础飞速发展&#xff0c;而医疗服务行业的发展却进展缓慢&#xff0c;传统的医疗服务行业已经逐渐不满足民众的需求&#xff0c;有些还在以线下预约挂号的方式接待病人&#xff0c;为此设计一个医疗平台系统很有必要。此类系统…

Stable Diffusion lora训练(一)

一、不同维度的LoRA训练步数建议 2D风格训练 数据规模&#xff1a;建议20-50张高质量图片&#xff08;分辨率≥10241024&#xff09;&#xff0c;覆盖多角度、多表情的平面风格。步数范围&#xff1a;总步数控制在1000-2000步&#xff0c;公式为 总步数 Repeat Image Epoch …

网络空间安全(37)获取webshell方法总结

一、直接上传获取Webshell 这是最常见且直接的方法&#xff0c;利用网站对上传文件的过滤不严或存在漏洞&#xff0c;直接上传Webshell文件。 常见场景&#xff1a; 许多PHP和JSP程序存在此类漏洞。例如&#xff0c;一些论坛系统允许用户上传头像或心情图标&#xff0c;攻击者可…

第十三次CCF-CSP认证(含C++源码)

第十三次CCF-CSP认证 跳一跳满分题解 碰撞的小球满分题解遇到的问题 棋局评估满分题解 跳一跳 题目链接 满分题解 没什么好说的 基本思路就是如何用代码翻译题目所给的一些限制&#xff0c;以及变量应该如何更新&#xff0c;没像往常一样给一个n&#xff0c;怎么读入数据&…

swagger ui 界面清除登录信息的办法

我们在开发过程中&#xff0c;用swagger ui 测试接口的时候&#xff0c;可能会要修改当前登录的用户。 但是如果我们在谷歌中对调试的本地swagger ui 登录地址存储过账户密码&#xff0c;每次启动项目调试之后&#xff0c;都会自动登录swagger ui &#xff0c;登录界面一闪就…

TensorFlow 的基本概念和使用场景

TensorFlow 是一个由 Google 开发的开源机器学习框架&#xff0c;主要用于构建和训练深度学习模型。下面是一些 TensorFlow 的基本概念和使用场景&#xff1a; 基本概念&#xff1a; 张量&#xff08;Tensor&#xff09;&#xff1a;在 TensorFlow 中&#xff0c;数据以张量的…

基于x11vnc的ubuntu远程桌面

1、安装VNC服务 sudo apt install x11vnc -y2、创建连接密码 sudo x11vnc -storepasswd3、安装lightdm服务 x11vnc 在 默认的 GDM3 中不起作用&#xff0c;因此需要使用 lightdm 桌面管理环境 sudo apt install lightdm -y切换至lightdm&#xff0c;上一步已经切换则跳过该…

Cursor解锁Claude Max,助力AI编程新突破!

Cursor 最新推出的 Claude Max 模型&#xff0c;以其卓越的性能和创新的能力&#xff0c;正在重新定义我们对 AI 辅助编程的认知。这款搭载 Claude3.7 大脑的超级模型&#xff0c;不仅具备超强智能&#xff0c;还凭借一系列技术突破&#xff0c;向传统 AI 编程工具发起了挑战。…

ESP8266 与 ARM7 接口-LPC2148 创建 Web 服务器以控制 LED

ESP8266 与 ARM7 接口-LPC2148 创建 Web 服务器以控制 LED ESP8266 Wi-Fi 收发器提供了一种将微控制器连接到网络的方法。它被广泛用于物联网项目,因为它便宜、体积小且易于使用。 在本教程中,我们将 ESP8266 Wi-Fi 模块与 ARM7-LPC2148 微控制器连接,并创建一个 Web 服务…

通过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约束 对管脚进行约束&#xff0c;对应的约束语句&#xff1a; set_property -dict {PACKAGE_PIN AJ16 IOSTANDARD LVCMOS18} [get_ports "led[0]" ] 上面是单端的管脚&…

实现前端.ttf字体包的压缩

前言 平常字体包都有1M的大小&#xff0c;所以网络请求耗时会比较长&#xff0c;所以对字体包的压缩也是前端优化的一个点。但是前端如果想要特点字符打包成字体包&#xff0c;网上查阅资料后&#xff0c;都是把前端代码里面的字符获取&#xff0c;但是对于动态的内容&#xf…

uni-app集成保利威直播、点播SDK经验FQ(二)|小程序直播/APP直播开发适用

通过uniapp集成保利威直播、点播SDK来开发小程序/APP的视频直播能力&#xff0c;在实际开发中可能会遇到的疑问和解决方案&#xff0c;下篇。更多疑问请咨询19924784795。 1.ios不能后台挂起uniapp插件 ios端使用后台音频播放和画中画功能&#xff0c;没有在 manifest.json 进…

Sensodrive机器人力控关节模组SensoJoint在海洋垃圾清理机器人中的拓展应用

海洋污染已成为全球性的环境挑战&#xff0c;其中海底垃圾的清理尤为困难。据研究&#xff0c;海洋中约有2600万至6600万吨垃圾&#xff0c;超过90%沉积在海底。传统上&#xff0c;潜水员收集海底垃圾不仅成本高昂&#xff0c;而且充满风险。为解决这一问题&#xff0c;欧盟资助…

Git的基本指令

一、回滚 1.git init 在项目文件夹中打开bash生成一个.git的子目录&#xff0c;产生一个仓库 2.git status 查看当前目录下的所有文件的状态 3.git add . 将该目录下的所有文件提交到暂存区 4.git add 文件名 将该目录下的指定文件提交到暂存区 5.git commit -m 备注信…

Vitis 2024.1 无法正常编译custom ip的bug(因为Makefile里的wildcard)

现象&#xff1a;如果在vivado中&#xff0c;添加了自己的custom IP&#xff0c;比如AXI4 IP&#xff0c;那么在Vitis&#xff08;2024.1&#xff09;编译导出的原本的.xsa的时候&#xff0c;会构建build失败。报错代码是&#xff1a; "Compiling blank_test_ip..."…

Elasticsearch 在航空行业:数据管理的游戏规则改变者

作者&#xff1a;来自 Elastic Adam La Roche 数字化客户体验不再是奢侈品&#xff0c;而是欧洲航空公司必不可少的需求。它推动了客户满意度&#xff0c;提升了运营效率&#xff0c;并创造了可持续的竞争优势。随着行业的不断发展&#xff0c;优先投资前沿数字技术和平台的航空…

DeepSeek 模型的成本效益深度解析:低成本、高性能的AI新选择

网罗开发 &#xff08;小红书、快手、视频号同名&#xff09; 大家好&#xff0c;我是 展菲&#xff0c;目前在上市企业从事人工智能项目研发管理工作&#xff0c;平时热衷于分享各种编程领域的软硬技能知识以及前沿技术&#xff0c;包括iOS、前端、Harmony OS、Java、Python等…