[db:标题]

摘要:select 2.1 简介 ​ select函数可以用于实现高效的多路复用 IO,同时处理多个文件描述符的事件,包括监听可读、可写和异常条件,具有阻塞和非阻塞模式,并可以设置超时时间。这使得程序能够高效地处理并发任务,提高性能和响应性。
select 2.1 简介 ​ select函数可以用于实现高效的多路复用 I/O,同时处理多个文件描述符的事件,包括监听可读、可写和异常条件,具有阻塞和非阻塞模式,并可以设置超时时间。这使得程序能够高效地处理并发任务,提高性能和响应性。 2.2 select函数 ​ 头文件:#include <sys/select> ​ 函数原型:int select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, struct timeval* timeout); ​ 函数参数: ​ nfds:监视文件描述符的最大值加一(文件描述符集合中所有的文件描述符的最大值+1) ​ readfds:指向一个文件描述符集合,用于监视是否有数据可读。 ​ writefds:指向一个文件描述符集合,用于监视是否可以写入数据。 ​ exceptfds:指向一个文件描述符集合,用于监视是否有异常情况。 ​ timeout:指向一个struct timeval结构体,表示超时时间,即select函数最多等待的时间。 ​ 结构体struct timeval 的成员: ​ time_t tv_sec:表示秒数。 ​ suseconds_t tv_usec:表示微妙数。 ​ 函数返回值: ​ 成功返回准备就绪的文件描述符总数。 ​ 监听超时则返回0。 ​ 发生错误返回-1。 2.3 select的几个宏函数 2.3.1将指定的一个文件描述符从集合中清除 ​ 函数原型:FD_CLR(int fd, fd_set *set); ​ 函数参数:fd为指定的文件描述符,set为指定的文件描述符集合 2.3.2 将指定的文件描述符集合清空,所有位置都置为0 ​ 函数原型:FD_ZERO(fd_set *set); ​ 函数参数:set为指定的文件描述符集合 2.3.3 将指定的文件描述符加入到指定的集合中 ​ 函数原型:FD_SET(int fd, fd_set *set); ​ 函数参数:fd为指定的文件描述符,set为指定的文件描述符集合 2.3.4 判断指定的文件描述符是否在某个文件描述符集合中 ​ 函数原型:FD_ISSET(int fd, fd_set *set); ​ 函数参数:fd为指定的文件描述符,set为指定的文件描述符集合 2.4 使用select创建一个多路io复用的服务端: ​ 第一步:创建套接字。 ​ 第二步:准备一些变量和常量,用于记录最大文件描述符,客户端发来的数据,循环次数,条件判断等待。 ​ 第三步:初始化本地(服务器)地址结构体sockaddr_in。 ​ 第四步:将套接字与本地地址绑定,并且建议判断一下是否绑定成功。 ​ 第五步:切换为监听状态。 ​ 第六步:进入一个无限循环然后持续监听。 ​ 马上进入循环时初始化文件描述符集合,进入后将刚才监听的文件描述符添加到里面。 ​ 在所有已连接的客户端文件描述符集合中寻找最大的文件描述符,然后记录下来。 ​ 使用select函数对整个文件描述符集合进行监听,如果监听失败则退出程序,如果有文件描述符可操作, 则进行具体操作。 ​ 当select监听有变化则检测监听的套接字是否有新的连接请求,如果有则使用accept接收连接,并且将accept返回的已经和客户端建立连接的描述符加入到已连接的客户端数组中。 ​ 处理客户端的请求。遍历已连接的客户端数组,逐个判断每个客户端文件描述符数组中的元素是否中文件描述符集合中,如果在则代表有数据可读。 ​ 从客户端接收数据,并且进行处理。如果无法接收数据则关闭客户端文件描述符然后将其从描述符集合中移除。否则就对客户端发来的数据进行相关操作。 ​ 第七步:当循环结束后,记得关闭所有已连接的客户端文件描述符和服务器文件描述符。
阅读全文