CMU 15-213 CSAPP:网络编程与 Web 服务器的底层构建(Network)
写在前面前面我们探讨了内存、汇编、异常控制流和本地 I/O现在我们要把视线投向外部世界。网络编程其实并不神秘在 Unix 的“万物皆文件”哲学下网络连接不过就是一个特殊的文件描述符Socket fd。在这篇笔记中我们将从底层的以太网聊起一步步搭建起 Socket 管道最后亲手解剖一个真实的 Web 服务器是如何运作的。Lec 21 Network Programming Part 1服务端 客户端 事务 (Client-Server Transaction)几乎所有的网络应用都是基于 Client-Server 模型的。Server (服务端):管理资源Resource提供服务Service。它像一台自动售货机永远在被动等待并响应请求。Client (客户端):主动发起请求获取服务。注意Client 和 Server 是进程 (Process)的概念而不是机器的概念。一台物理主机上可以同时跑着成百上千个 Client 和 Server 进程比如亚马逊的服务器群。最底层以太网段管理在最底层的硬件层面以太网Ethernet负责把数据从一台机器搬到另一台机器。MAC 地址:每块网卡出厂时都有一个全球唯一的 48 位地址如00:16:EA:54:54:E6。Hub (集线器) 与数据帧 (Frames):在早期的以太网中主机把数据切成小块Frames发给 HubHub 会极其“无脑”地把这个 Frame 复制并广播给所有连在上面的端口。所有的网卡都会收到这个 Frame但只有发现 MAC 地址和自己匹配的网卡才会把它接收进内存。因特网应用的硬件软件管理TCP/IP 协议栈是构建在底层局域网之上的跨网络抽象它对上层应用屏蔽了底层物理网络的复杂性。IPv4 IPv6IPv4:32 位地址约 43 亿个。最初设计时没人能想到互联网会这么庞大导致地址早已枯竭。由于 NAT (网络地址转换) 技术的续命目前世界上绝大多数的流量依然跑在 IPv4 上。IPv6:128 位地址。号称“能给地球上的每一粒沙子分配一个 IP”。在现代网络编程中我们应该尽量编写协议无关 (Protocol-Independent)的代码让系统自己去适配 IPv4 还是 IPv6。DNS (域名解析系统)人类记不住 IP 地址只能记住域名如www.cmu.edu。DNS 就是互联网的电话本。它是一个庞大的分布式数据库从未命名的根节点开始逐层向下解析.edu - cmu - www最终将域名转化为机器认识的 IP 地址。著名的 Port (端口) 和 Service Name一台主机只有一个 IP但上面可能跑着 Web 服务、邮件服务和 SSH 服务。为了区分数据包该交给哪个进程引入了端口 (Port)的概念16位0~65535。IP 地址找大楼 端口号找房间 唯一的通信端点Socket。知名端口Well-known ports通常被保留定义在 Linux 的/etc/services文件中Echo:7SSH:22Email (SMTP):25Web (HTTP):80Socket Interface (核心打通管道)这是网络编程的灵魂理解 Socket 最好的方法是**“打电话模型”**。1.socket()建立管道 —— 【买一部手机】创建一个 Socket 文件描述符 (fd)。参数domain(IPv4/IPv6),type(一般是流式SOCK_STREAM即 TCP),protocol(一般为 0)。2.bind()绑定端口 —— 【去营业厅办一个手机号】服务端专用。内核把你的 Socket fd 和一个具体的本地 IP 及端口号绑定。告诉系统“如果有发往 80 端口的数据包请交给我。”3.listen()监听端口 —— 【开机调大铃声准备接听】服务端专用。默认创建的 Socket 是主动去连别人的Client 视角。调用listen会把这个 Socket 转换成被动监听模式。backlog: 这是一个“候诊室”的大小。如果并发连接太多服务器处理不过来最多允许多少个连接在队列里排队。4.accept()服务端接受请求 —— 【接起电话开启通话子频道】服务端阻塞在这里直到有客户端连进来。灵魂设定accept会返回一个全新的 Socket fd (connfd) 用来专门和这个客户进行数据收发而原来的监听 fd (listenfd) 继续保持监听状态等待下一个客户进来。5.connect()客户端发起连接 —— 【拨打号码】客户端主动向 Server 发起连接引发 TCP 三次握手。成功后clientfd就可以自由地read/write交流了。现代的地址转换神器getaddrinfo以前写网络代码要自己查 DNS 把域名转成 IP还要手工处理字节序转换大端转小端极其痛苦。现在我们使用getaddrinfo。它是线程安全的可重入不仅通吃 IPv4 和 IPv6而且直接吐出一个链表里面包含了创建 Socket 需要的所有参数。常见套路顺着链表遍历挨个尝试socket()和connect()或bind()直到成功为止。Lec 22 Network Programming Part IISocket Address Structures (令人抓狂的 C 语言强转)C 语言没有面向对象的多态。网络 API 要求传入一个通用的sockaddr结构但我们实际操作时用的是专属的sockaddr_in针对 IPv4。所以你在代码里会看到满天飞的强制类型转换(struct sockaddr *)。这纯粹是历史遗留的丑陋设计习惯就好。Socket Helper封装open_listenfd为了不每次都写一堆繁琐的 Socket 初始化代码CSAPP 提供了一个极为好用的 Helper 包装函数。核心避坑指南 (SO_REUSEADDR):留意幻灯片里的setsockopt行。如果你杀掉一个服务端程序然后马上重启系统常常会报错“Address already in use (地址已被占用)”。因为操作系统会把刚才的端口保持在TIME_WAIT状态一段时间以防残留包。加上SO_REUSEADDR标志可以消除这个恶心的错误允许你立即重启绑定同一端口。迭代 Echo Server (Iterative Server)这是一个最基础的服务端架构。while(1)循环里不断地accept把收到的数据原封不动发回去Echo。它的致命弱点因为是串行Iterative的一次只能处理一个客户。如果黑客 A 连上之后故意不发数据也不挂断整个服务器就完全阻塞挂死了其他任何人都连不进来。这就是为什么后面必然要学习**并发服务器多进程/多线程/I/O 多路复用**的原因。Web (HTTP 原理初探)我们在浏览器里看到的五彩斑斓的网页本质上都是文本和二进制字节流。通过 MIME 扩展类型如text/html,image/jpeg服务器告诉浏览器发过去的数据到底该如何渲染。访问网页其实就是访问服务器硬盘上的一个文件并把它读过来。HTTP 请求 (Requests) 响应 (Responses)HTTP 是一个无状态的纯文本协议非常容易阅读。请求行Method URI Version例如GET /index.html HTTP/1.1响应行Version Status Code Status Msg例如HTTP/1.1 200 OK或HTTP/1.1 404 Not Found在头部之后会跟着一个空行\r\n空行之后就是真正的网页内容体Body了。小操作TINY Web Server 的逻辑实现一个简单的 Web 服务器其实只需这几步建立 Socket 等待连接accept。从连接中读取客户端发来的文本请求。把字符串切开提取出 Method (GET) 和 URI。判断是静态内容返回一个写死的 HTML 文件还是动态内容执行一个程序把程序的输出返回给客户端。CGI 与dup2的终极黑魔法 (Serving Dynamic Content)如果是动态内容客户端怎么传参数给服务端计算服务端又怎么把算好的结果送回给远方的客户端传参参数被塞在 URI 的问号?后面用分隔。空格会被转义为%20。计算服务器收到请求后调用fork()产生一个子进程。子进程把解析出的参数设置到操作系统的环境变量中然后用我们学过的execve()加载一个独立的 C 语言可执行程序CGI 脚本去运行。那个 C 程序直接用getenv就能拿到参数进行计算最为惊艳的设计 (dup2移花接木)那个独立运行的 C 语言计算程序并不知道什么是网络它只是单纯地计算完毕然后用printf()打印结果。printf()默认是输出到STDOUT(终端显示器) 的。但是在执行execve之前父进程巧妙地调用了dup2(fd, STDOUT_FILENO)。这一招瞬间将标准输出的管道重定向到了网络的 Socket fd上于是那个无辜的子程序调用printf(计算结果是 5)时屏幕上什么也没有这串字符顺着网线飞跃大洋直接出现在了客户端的浏览器屏幕上这就是 Unix 底层抽象的顶级魅力

相关新闻

有没有不易触发 AI 检测、适合学生使用的论文助手?实测靠谱工具深度盘点

有没有不易触发 AI 检测、适合学生使用的论文助手?实测靠谱工具深度盘点

每到毕业季、课程论文提交节点,很多同学都会陷入双重焦虑:知网、维普查重重复率居高不下,好不容易降完重,又被学校新版 AIGC 人工智能内容检测系统标记高疑似率,直接面临导师打回、学术审核预警的风险。市面上绝大多数…

2026/10/12 21:29:44 阅读更多 →
排列与组合介绍

排列与组合介绍

2026/10/9 11:13:59 阅读更多 →
条件概率介绍

条件概率介绍

2026/10/9 23:09:47 阅读更多 →

最新新闻

DeepSeek Harness 插件体系从入门到精通:安装、配置与离线部署全指南

DeepSeek Harness 插件体系从入门到精通:安装、配置与离线部署全指南

1. 从零理解 DeepSeek Harness 插件体系到底在解决什么问题很多人第一次接触 DeepSeek Harness 的时候,脑子里冒出来的第一个问题往往是:这玩意儿跟直接用命令行调模型有什么区别?我一开始也是这个反应。后来真正把插件机制跑通之后才明白&am…

2026/10/14 14:40:57 阅读更多 →
Zabbix监控MariaDB实践:核心指标、触发器与告警配置全解析

Zabbix监控MariaDB实践:核心指标、触发器与告警配置全解析

先聊点实际的。上个月我接手了一台总是半夜告警的数据库服务器,CPU、内存指标看起来都没问题,Zabbix主机层面一切都是绿的,可业务方就是反馈查询慢、页面转圈。后来一查,问题全在MariaDB自身的连接数被打满、慢查询堆积上。主机活…

2026/10/14 14:40:57 阅读更多 →
TypeScript入门指南:静态类型与工程实践

TypeScript入门指南:静态类型与工程实践

1. TypeScript 基础入门:为什么选择它?第一次接触 TypeScript 是在 2016 年维护一个大型前端项目时。当时 JavaScript 代码已经膨胀到 3 万行,每次修改功能都像在雷区拆弹——你永远不知道哪个变量的类型变化会引发连锁崩溃。直到团队引入 Ty…

2026/10/14 14:40:56 阅读更多 →
博学谷习题界面开发实战:Android ListView自定义Adapter与判分逻辑实现

博学谷习题界面开发实战:Android ListView自定义Adapter与判分逻辑实现

做这个习题界面之前,我其实纠结了一段时间。博学谷这个模拟在线学习App做到第十一期,前面的章节页、详情页、视频播放流程都已经跑通了,用户能浏览课程、能看介绍,但一直都缺一个自我检验的入口。习题界面就是补上这个缺口&#x…

2026/10/14 14:40:56 阅读更多 →
三维模型导入技术解析与星图云实战指南

三维模型导入技术解析与星图云实战指南

1. 三维模型导入的核心价值与挑战在数字内容创作领域,三维模型就像建筑师的砖瓦。最近半年我参与了17个跨行业的三维项目,发现模型导入环节平均消耗了团队23%的有效工作时间。其中格式兼容性问题导致的返工占比高达68%,这个数据让我意识到系统…

2026/10/14 14:40:56 阅读更多 →
ComfyUI本地部署全攻略:从整合包到手动部署,跑通AI绘画工作流

ComfyUI本地部署全攻略:从整合包到手动部署,跑通AI绘画工作流

在家用电脑上折腾出一个自己的 ComfyUI,这事说难不难,说简单,又确实能把一大批人挡在门外。我见过太多人收藏了十几篇部署教程,结果打开一看全是"打开命令行输入 pip install xxx",人直接就懵了;…

2026/10/14 14:39:56 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →