CMU 15-213 CSAPP:网络编程与 Web 服务器的底层构建(Network)

发布时间:2026/7/23 17:50:52

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 底层抽象的顶级魅力

相关新闻

049、双管正激的占空比限制

049、双管正激的占空比限制

2026/7/23 17:40:52

049 双管正激的占空比限制 从一块冒烟的板子说起 去年帮朋友调试一款48V转12V/20A的通信电源,用的是双管正激拓扑。样机第一次上电,轻载正常,加到10A负载,MOS管炸了,驱动芯片也挂了。拆下来看,两个MOS管的漏源极都短路了,变压器初级绕组有烧焦痕迹。 朋友说:“我算过…

使用yolo11训练无人机视角罂粟检测数据集VOC+YOLO格式3648张1类别步骤和流程

使用yolo11训练无人机视角罂粟检测数据集VOC+YOLO格式3648张1类别步骤和流程

2026/7/23 17:40:52

【数据集介绍】 注意数据集中存在增强图片主要是旋转增强,占据数据量大约一半,注意查看图片 数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量…

048、双管正激变换器原理

048、双管正激变换器原理

2026/7/23 17:40:52

048、双管正激变换器原理 上个月帮朋友救一个项目,48V转12V/20A的电源模块,单管正激拓扑,MOS管和续流二极管烧了一轮又一轮。客户催得紧,朋友急得嘴角起泡。我拿到板子一看,复位绕组和漏感尖峰处理得稀碎,MOS管关断瞬间电压应力直接飙到200V+,管子不炸才怪。后来改成双…

私企面经cao

私企面经cao

2026/7/23 20:30:58

Java面试高频:AOC、AOP 线程池 一、面试口述极简版(直接背,30秒答完) AOC、AOP 口述答案 AOP是面向切面编程,是一种编程思想。核心就是把项目中通用的横切逻辑,比如日志、事务、权限校验、接口限流这些和业…

审计抽样怎么选方法?货币单元抽样(PPS)、变量抽样、分层抽样与全量审计的工程对比

审计抽样怎么选方法?货币单元抽样(PPS)、变量抽样、分层抽样与全量审计的工程对比

2026/7/23 20:30:58

背景:抽样是审计的"效率闸门" 审计不可能把每一笔凭证都翻一遍,抽样因此成为连接"审计质量"与"成本"的闸门。选错抽样方法,要么样本量过大把人累死,要么覆盖率不足把风险漏掉。近十年抽样方法本身没…

TypeScript AI Agent运行时系统Claude Code架构解析

TypeScript AI Agent运行时系统Claude Code架构解析

2026/7/23 20:30:58

1. Claude Code 项目概述Claude Code 是一个基于 TypeScript 开发的 AI Agent 运行时系统,它不仅仅是一个简单的 CLI 聊天封装,而是一个完整的 Agent 运行时环境。这个系统能够自主感知环境(如读取文件系统、Git 状态)&#xff0c…

Django毕设项目:基于Django的鲜花预售与节日活动营销商城系统 移动端适配鲜花购物商城系统设计 (源码+文档,讲解、调试运行,定制等)

Django毕设项目:基于Django的鲜花预售与节日活动营销商城系统 移动端适配鲜花购物商城系统设计 (源码+文档,讲解、调试运行,定制等)

2026/7/23 20:30:58

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

大模型Function Calling机制:语义可执行性解析与实践

大模型Function Calling机制:语义可执行性解析与实践

2026/7/23 20:30:58

1. Function Calling 机制解析:为什么"火星天气"会触发工具调用?在测试 Function Calling 功能时,我们发现一个有趣现象:当询问"火星天气"时,系统会正常调用天气查询工具,而输入"…

深入解析SCI/UART异步串行通信:从基础原理到中断DMA实战应用

深入解析SCI/UART异步串行通信:从基础原理到中断DMA实战应用

2026/7/23 20:20:58

1. SCI/UART通信基础与核心概念解析串行通信接口,也就是我们常说的SCI,或者更广为人知的UART,是嵌入式开发者和硬件工程师打交道最多的外设之一。无论你是用STM32、TI的C2000系列,还是其他任何一款微控制器,只要涉及到…

微服务进阶:服务网格与Istio

微服务进阶:服务网格与Istio

2026/7/23 3:40:08

541|微服务进阶:服务网格与Istio 上篇文章我们聊了微服务的基本概念和拆分方法。 但微服务多了,问题也多了: 服务之间怎么通信? 怎么监控每个服务的调用链路? 熔断、限流、重试怎么做? 安全认证怎么统一? 以前这些都靠SDK库(比如Hystrix、Feign),每个服务都要集成…

零售超级终端全域协同:ShareKit 碰一碰商品流转业务落地案例

零售超级终端全域协同:ShareKit 碰一碰商品流转业务落地案例

2026/7/23 4:40:05

一、零售门店全域协同业务背景与行业痛点 1.1 门店超级终端设备矩阵(连锁便利店/商超标准配置) 自助收银Kiosk一体机:顾客结算、自助核销优惠券、商品素材预览;运营折叠平板:店长后台商品上新、图片录入、活动配置、…

噗叽短视频界面分析

噗叽短视频界面分析

2026/7/23 1:54:13

1 和小红书类似,可以采用类似判断方法------------其实他比小红书好判断,因为他没有图片,控件位置几乎是固定的,都不用判断------------2 因为他没有点赞按钮------------而且几乎所有控件位置都是完全一样的,所以我就…

企业级AI搜索落地选型实战手册(含LLM+RAG+Hybrid架构对比矩阵与ROI测算模板)

企业级AI搜索落地选型实战手册(含LLM+RAG+Hybrid架构对比矩阵与ROI测算模板)

2026/7/23 0:09:56

更多请点击: https://kaifayun.com 第一章:企业级AI搜索落地选型实战手册(含LLMRAGHybrid架构对比矩阵与ROI测算模板) 企业级AI搜索系统落地成败,核心在于技术选型与业务价值的精准对齐。盲目堆砌大模型能力或过度依赖…

TM4C129LNCZAD外设实战:LCD、比较器与PWM寄存器配置详解

TM4C129LNCZAD外设实战:LCD、比较器与PWM寄存器配置详解

2026/7/23 0:09:56

1. 项目概述与核心价值在嵌入式系统开发,尤其是基于ARM Cortex-M内核的微控制器项目中,深入理解并熟练配置芯片的片上外设,是从“点亮LED”迈向“实现复杂系统功能”的关键一步。Tiva™ TM4C129LNCZAD作为TI公司Cortex-M4F家族中的高性能成员…

AtomCode `fmt_dur` 争议溯源:两个函数、三段演进、四个事实

AtomCode `fmt_dur` 争议溯源:两个函数、三段演进、四个事实

2026/7/23 0:09:56

一、快速声明与争议背景本文是对 AtomCode 终端 spinner 时长显示 fmt_dur 相关说法的事实性核验。2026 年 7 月 CSDN 上出现两篇互相矛盾的博文,近期又有 AI 在对话中输出格式描述 XhYm / YmZs / Zs。本文基于 AtomCode 仓库 main4677ddfa 及全分支 Git 历史给出可…