Linux网络编程之socket编程(九)-select

前一篇我们介绍了select相关内容,本次我们将继续深入学习select函数,学习读、写、异常事件发生的条件以及用select改进回射服务器程序。

1.select函数

int select(int nfds, fd_set *readfds, fd_set *writefds, fs_set *excepfds, struct timeval *timeout)
ndfs:是最大描述符+1

(1)select相当于一个中心管理器,能够统一管理多个I/O,一旦其中一个或多个I/O产生了我们感兴趣的事件,就会被select检测到。并返回I/O事件发生的个数。

(2)通常将用select实现的服务器,称为并发服务器。当select检测到事件后,一个个的遍历事件,然后依次处理之。这种服务器是并发的但不是并行的。
(3)并发不代表并行,用select是无法实现并行的,它无法充分利用多核CPU。(对单核CPU来说,是没有并行可言的)
(4)对此,可以使用多个进程或线程使用select,达到“并行”的目的。

2.读、写、异常事件发生条件

  • 可读:
    • 套接口缓冲区有数据可读
    • 连接的读一半关闭,即接收FIN段,读操作将返回0
    • 如果是监听套接口,已完成连接队列不为空时
    • 套接口上发生了一个错误待处理,错误可以通过getsockopt指定SO_ERROR选项来获取
  • 可写:
    • 套接口发送缓冲区有空间容纳数据
    • 连接的写一半关闭。即收到RST段之后,再次调用write操作。
    • 套接口上发生了一个错误待处理,错误可以通过getsockopt指定SO_ERROR选项来获取
  • 异常:
    • 套接口存在带外数据
3.用select改进回射服务器

(1)回想之前服务器端实现并发的设计机制:fork()一个进程出来,子进程处理已连接套接口的通信模块echo_srv;父进程负责监听套接口的监听连接。
(2)此处用select取代上述的并发设计。只需要一个进程即可实现:select可以统一管理监听套接口发生的事件和已连接套接口发生的事件。

(3)完整echosrv.c源码

(5)客户端源码可参考上一篇博文——用select改进后的客户端。

小结:
(1)用select改进后的回射客户/服务器模型较多进程回射客户/服务器有了一定的性能提升。
(2)本质思想,用select来管理多个套接口是否产生事件。要管理的套接口有两类:一类是监听套接口,另一类是已连接套接口。
(3)初始状态,只有一个套接口感兴趣——监听套接口,我们就将监听套接口放入集合中。然后调用select判定是否是监听套接口在集合中,若是,表明监听套接口产生了可读事件——这意味着对等方已经连接过来了。accept不再阻塞–>进行返回–>获得一个已连接套接口。并将该已连接套接口放入集合,以便下次我们可以关心其产生感兴趣事件。
(由于我们是用单进程的方式来实现,若需要维护与多个客户端的连接,就需要将该已连接套接口保存到一个数组中。)

发表评论

电子邮件地址不会被公开。 必填项已用*标注