I/O 复用

IO multiplexing 多路复用, 也称事件驱动 IO(event driven IO)。通常, 单个进程无法实现同时处理多个 IO, 而基于 select/epoll 方式, 可以轮询所负责的 socket, 一旦任意一个或多个 socket 就绪(可读/可写/异常), 才继续执行, 使得进程不会阻塞在套接字上, 二十 select/epoll 函数上.

i/o 多路复用 6-3

阻塞式

以阻塞式 TCP回射 的客户端 str_cli 程序来说:

程序先阻塞与用户向服务器发送(writen)数据, 等待用户输入, 而后阻塞与从 socket 获取(readline)数据. 用户一直不输入, 则一直阻塞, 即便服务端已有数据需要客户端处理.

select 复用式

select 函数结构如下:

select 可以在预设的最大监听数下, 监听若干个套接字的读, 写或异常状况的一个或多个, 并可以设定阻塞时间.

select 参数意思分别为最大监听的套接字个数加 1, 是否可读, 可写, 异常, 阻塞时间. 可以通过可读可写异常参数定义套接字就绪条件, 根据需要可以选择性制空, 时间置空则一直等待, 知道有套接字就绪位置.

fd_set 为一个套接字相关的结构体, 并赋予了四个方法

FD_ZERO 初始化
FD_SET 打开描述符
FD_CLR 关闭描述符
FD_ISSET 判断描述符是否就绪

以下为 select 改写的 str_cli 函数:

其中, 先计算最大需要监听的描述符个数 maxfdp1, 而后调用 select() 函数, 这里之间听套接字是否可读, 如果没有就绪的套接字, 则一直阻塞下去.

一旦有套接字可读, 则 select() 停止阻塞, 程序继续执行, 通过 FD_ISSET 函数判断套接字是否就绪, 是则执行.

以上, 便规避了直接阻塞与 I/O 上, 而是先由 select 托管, 直到有套接字可用, 再执行下去.

另外, 本程序还有一个错误,

当客户端获取完了所有用户数据的时候, return 关闭, 但是此时只能保证客户端数据全部发送给服务端了, 但是不能保证服务端处理完成, 更不能保证所有数据都接收完毕, 故此时应当使用更优雅的关闭方式. 代码如下:

shutdown(int socketfd, int howto) 函数可以选择行的关闭读或写.

鸣谢 Unix 网络编程

Hello world!
文章已创建 196

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部