mirror of
https://github.com/riba2534/TCP-IP-NetworkNote.git
synced 2026-07-11 15:35:44 +08:00
完成了第 12 章 I/O 复用
This commit is contained in:
73
README.md
73
README.md
@@ -3263,7 +3263,7 @@ timeout: 调用 select 函数后,为防止陷入无限阻塞的状态,传递
|
||||
1. 文件描述符的监视(检查)范围是?
|
||||
2. 如何设定 select 函数的超时时间?
|
||||
|
||||
第一,文件描述符的监视范围和 select 的第一个参数有关。实际上,select 函数要求通过第一个参数传递监视对象文件描述符的数量。因此,需要得到注册在 fd_set 变量中的文件描述符数。但每次信件文件描述符时,其值就会增加 1 ,故只需将最大的文件描述符值加 1 再传递给 select 函数即可。加 1 是因为文件描述符的值是从 0 开始的。
|
||||
第一,文件描述符的监视范围和 select 的第一个参数有关。实际上,select 函数要求通过第一个参数传递监视对象文件描述符的数量。因此,需要得到注册在 fd_set 变量中的文件描述符数。但每次新建文件描述符时,其值就会增加 1 ,故只需将最大的文件描述符值加 1 再传递给 select 函数即可。加 1 是因为文件描述符的值是从 0 开始的。
|
||||
|
||||
第二,select 函数的超时时间与 select 函数的最后一个参数有关,其中 timeval 结构体定义如下:
|
||||
|
||||
@@ -3289,6 +3289,77 @@ select 返回正整数时,怎样获知哪些文件描述符发生了变化?
|
||||
|
||||
下面是一个 select 函数的例子:
|
||||
|
||||
- [select.c](https://github.com/riba2534/TCP-IP-NetworkNote/blob/master/ch12/select.c)
|
||||
|
||||
编译运行:
|
||||
|
||||
```shell
|
||||
gcc select.c -o select
|
||||
./select
|
||||
```
|
||||
|
||||
结果:
|
||||
|
||||

|
||||
|
||||
可以看出,如果运行后在标准输入流输入数据,就会在标准输出流输出数据,但是如果 5 秒没有输入数据,就提示超时。
|
||||
|
||||
#### 12.2.6 实现 I/O 复用服务器端
|
||||
|
||||
下面通过 select 函数实现 I/O 复用服务器端。下面是基于 I/O 复用的回声服务器端。
|
||||
|
||||
- [echo_selectserv.c](https://github.com/riba2534/TCP-IP-NetworkNote/blob/master/ch12/echo_selectserv.c)
|
||||
|
||||
编译运行:
|
||||
|
||||
```shell
|
||||
gcc echo_selectserv.c -o selserv
|
||||
./selserv 9190
|
||||
```
|
||||
|
||||
结果:
|
||||
|
||||

|
||||
|
||||
从图上可以看出,虽然只用了一个进程,但是却实现了可以和多个客户端进行通信,这都是利用了 select 的特点。
|
||||
|
||||
### 12.3 基于 Windows 的实现
|
||||
|
||||
暂略
|
||||
|
||||
### 12.4 习题
|
||||
|
||||
> 以下答案仅代表本人个人观点,可能不是正确答案。
|
||||
|
||||
1. **请解释复用技术的通用含义,并说明何为 I/O 复用。**
|
||||
|
||||
答:通用含义:在 1 个通信频道中传递多个数据(信号)的技术。IO复用就是进程预先告诉内核需要监视的IO条件,使得内核一旦发现进程指定的一个或多个IO条件就绪,就通过进程进程处理,从而不会在单个IO上阻塞了。
|
||||
|
||||
参考文章:[Linux网络编程-IO复用技术](https://www.cnblogs.com/luoxn28/p/6220372.html)
|
||||
|
||||
2. **多进程并发服务器的缺点有哪些?如何在 I/O 复用服务器中弥补?**
|
||||
|
||||
答:多进程需要进行大量的运算和大量的内存空间。在 I/O 复用服务器中通过 select 函数监视文件描述符,通过判断变化的文件描述符,来得知变化的套接字是哪个,从而实时应答来自多个客户端的请求。
|
||||
|
||||
3. **复用服务器端需要 select 函数。下列关于 select 函数使用方法的描述错误的是?**
|
||||
|
||||
答:以下加粗的为正确的描述。
|
||||
|
||||
1. 调用 select 函数前需要集中 I/O 监视对象的文件描述符
|
||||
2. **若已通过 select 函数注册为监视对象,则后续调用 select 函数时无需重复注册**
|
||||
3. 复用服务器端同一时间只能服务于 1 个客户端,因此,需要服务的客户端接入服务器端后只能等待
|
||||
4. **与多线程服务端不同,基于 select 的复用服务器只需要 1 个进程。因此,可以减少因创建多进程产生的服务器端的负担**。
|
||||
|
||||
4. **select 函数的观察对象中应包含服务端套接字(监听套接字),那么应将其包含到哪一类监听对象集合?请说明原因**。
|
||||
|
||||
答:应该包含到「是否存在待读取数据」,因为服务器端需要查看套接字中有没有可以读取的数据。
|
||||
|
||||
### 第 13 章 多种 I/O 函数
|
||||
|
||||
本章代码,在[TCP-IP-NetworkNote](https://github.com/riba2534/TCP-IP-NetworkNote)中可以找到。
|
||||
|
||||
### 13.1 send & recv 函数
|
||||
|
||||
|
||||
|
||||
## License
|
||||
|
||||
Reference in New Issue
Block a user