docs: 全面审查并修正所有章节文档内容

- 修正各章节中的错别字和术语错误(如 IPv4 大写规范、接收/接受区分等)
- 补充和完善部分习题答案
- 优化技术描述的准确性和专业性
- 合并所有章节内容到根 README.md

新增文件:
- CLAUDE.md: 项目开发指南
- .claude/agents/content-reviewer.md: 内容审查 subagent
- .claude/agents/merger.md: 文档合并 subagent

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
riba2534
2026-01-05 15:28:29 +08:00
parent f163bca3a9
commit d44ecdf807
23 changed files with 1933 additions and 825 deletions

View File

@@ -24,7 +24,7 @@ I/O 复用技术可以解决这个问题。
![](https://s2.ax1x.com/2019/01/23/kA8H81.png)
上图是一个纸杯电话系统,为了使得三人同时通话,说话时要同对着两个纸杯,接听时也需要耳朵同时对准两个纸杯。为了完成 3 人通话,可以进行如下图的改进:
上图是一个纸杯电话系统,为了使得三人同时通话,说话时要同对着两个纸杯,接听时也需要耳朵同时对准两个纸杯。为了完成 3 人通话,可以进行如下图的改进:
![](https://s2.ax1x.com/2019/01/23/kA8bgx.png)
@@ -107,7 +107,7 @@ readset: 将所有关注「是否存在待读取数据」的文件描述符注
writeset: 将所有关注「是否可传输无阻塞数据」的文件描述符注册到 fd_set 型变量,并传递其地址值。
exceptset: 将所有关注「是否发生异常」的文件描述符注册到 fd_set 型变量,并传递其地址值。
timeout: 调用 select 函数后,为防止陷入无限阻塞的状态,传递超时(time-out)信息
返回值: 发生错误时返回 -1,超时时返回0,。因发生关注的时间返回时,返回大于0的值,该值是发生事件的文件描述符数。
返回值: 发生错误时返回 -1超时时返回 0。因发生关注的事件返回时,返回大于 0 的值,该值是发生事件的文件描述符数。
*/
```
@@ -128,7 +128,7 @@ struct timeval
};
```
本来 select 函数只有在监视文件描述符发生变化时才返回。如果未发生变化,就会进入阻塞状态。指定超时时间就是为了防止这种情况的发生。通过上述结构体变量,将秒数填入 tv_sec 的成员,将微数填入 tv_usec 的成员,然后将结构体的地址值传递到 select 函数的最后一个参数。此时,即使文件描述符未发生变化,只要过了指定时间,也可以从函数中返回。不过这种情况下, select 函数返回 0 。因此,可以通过返回值了解原因。如果不想设置超时,则传递 NULL 参数。
本来 select 函数只有在监视文件描述符发生变化时才返回。如果未发生变化,就会进入阻塞状态。指定超时时间就是为了防止这种情况的发生。通过上述结构体变量,将秒数填入 tv_sec 的成员,将微数填入 tv_usec 的成员,然后将结构体的地址值传递到 select 函数的最后一个参数。此时即使文件描述符未发生变化只要过了指定时间也可以从函数中返回。不过这种情况下select 函数返回 0。因此可以通过返回值了解原因。如果不想设置超时则传递 NULL 参数。
#### 12.2.4 调用 select 函数查看结果
@@ -186,7 +186,7 @@ gcc echo_selectserv.c -o selserv
1. **请解释复用技术的通用含义,并说明何为 I/O 复用。**
答:通用含义:在 1 个通信频道中传递多个数据信号的技术。IO复用就是进程预先告诉内核需要监视的IO条件,使得内核一旦发现进程指定的一个或多个IO条件就绪,就通进程进处理,从而不会在单个IO上阻塞
答:通用含义:在 1 个通信频道中传递多个数据信号的技术。I/O 复用是指进程预先告诉内核需要监视的 I/O 条件,使得内核一旦发现进程指定的一个或多个 I/O 条件就绪(例如套接字变为可读或可写),就通进程进处理,从而进程不会在单个 I/O 操作上阻塞。
参考文章:[Linux网络编程-IO复用技术](https://www.cnblogs.com/luoxn28/p/6220372.html)
@@ -194,15 +194,15 @@ gcc echo_selectserv.c -o selserv
答:多进程需要进行大量的运算和大量的内存空间。在 I/O 复用服务器中通过 select 函数监视文件描述符,通过判断变化的文件描述符,来得知变化的套接字是哪个,从而实时应答来自多个客户端的请求。
3. **复用服务器端需要 select 函数。下列关于 select 函数使用方法的描述错误的是?**
3. **复用服务器端需要 select 函数。下列关于 select 函数使用方法的描述错误的是?**
答:以下加粗的为正确的描述。
答:错误的描述是 2 和 3。说明如下
1. 调用 select 函数前需要集中 I/O 监视对象的文件描述符
2. **若已通过 select 函数注册监视对象,则后续调用 select 函数时无需重复注册**
3. 复用服务器端同一时间只能服务于 1 个客户端,因此,需要服务的客户端接入服务器端后只能等待
4. **与多线程服务端不同,基于 select 的复用服务器只需要 1 个进程。因此,可以减少因创建多进程产生的服务器端的负担**
- 描述 1 正确:调用 select 函数前需要集中 I/O 监视对象的文件描述符
- 描述 2 错误:**每次调用 select 函数时都需要重新注册监视对象**,因为 select 函数调用后fd_set 变量会被修改,只保留发生变化的文件描述符位为 1。
- 描述 3 错误:**复用服务器端可以同时服务于多个客户端**,这正是 I/O 复用的核心优势——通过 select 函数同时监视多个套接字,哪个就绪就处理哪个。
- 描述 4 正确:与多进程/多线程服务端不同,基于 select 的复用服务器只需要 1 个进程,可以减少因创建多进程产生的服务器端的负担。
4. **select 函数的观察对象中应包含服务端套接字(监听套接字),那么应将其包含到哪一类监听对象集合?请说明原因**
答:应该包含到「是否存在待读取数据」,因为服务器端需要查看套接字中有没有可以读取的数据
答:应该包含到「是否存在待读取数据」(即 readset集合中。原因是服务端套接字监听套接字的作用是监听客户端的连接请求当有新的客户端发起连接时监听套接字变为「可读」状态此时 accept 函数不会阻塞,可以成功完成连接。因此需要监视监听套接字是否可读,以得知是否有新的连接请求到来