HTML5 Ubuntu 微软 wordpress shell mysql linux 开源 Windows linux命令 nginx 程序员 Android java php apache Firefox Python centos google

使用select机制处理多连接

 当服务器根据客户端的请求创建多个连接以后,每个连接对应不同的套接字,因为recv函数默认是阻塞的,会造成在等待一个客户端套接字返回数据的时候整个进程阻塞,而无法连接收其他客户端套接字数据,这时候需要一个可以处理多个连接的方法,socket库提供了两个函数select和poll用来等待一组套接字句柄的读写操作。

 Linux系统提供了select函数和poll函数两个网络套接字描述符。如程序员可以通过这两个函数的返回结果,知道那个套接字描述符上有数据处理,使用select函数和poll函数后,程序可以省去不断的伦向网络套接字描述符的步骤。在后台运行网络和poll函数可以显著提高网络应用程序的工作效率。

 select函数是比较常用的,函数定义有新的标准: 

  1. void FD_ZERO(fd_set *fdset);

  2. void FD_SET(int fd, fd_set *fdset);

  3. void FD_CLR(int fd, fd_set *fdset);

  4. int FD_ISSET(int fd, fd_set *fdset);

    下面简单介绍一下可读、可写和有异常的定义。

    可读的4种定义:(1)套接字缓冲区收到了足够的数据(和TCP的实现有关),也就是说这时调用recv()函数不会阻塞,而且返回一个大于0的值。(2)套接字的读半部被关闭,也就是说它收到了一个FIN标志。此时调用recv()函数返回0。(3)在服务器端套接字成功开始监听,并且完成了至少1个连接。也就是说这时调用accept()函数不会阻塞。(4)有一个套接字出错了,这时调用recv()函数则返回-1。

    可写的4中定义:(1)套接字的发送缓冲区有足够的空间接收数据此时调用send()函数不会阻塞且返回一个大于0的值。(2)套接字的写半部被关闭。(3)非阻塞的connect()函数成功建立了连接,或者失败。(4)有一个套接字出错了,这时调用send()函数则返回-1。
    根据不同的标准,使用select函数需要包含不同的头文件,select函数提供一种fd-set机制,fd-set是一组文件句柄的集合,参数n通常取select函数的fd-set中最大的一个文件句柄加1,参数readfds是要监控的读文件句柄集合,当readfds或者writefds有数据或者时间超时,select函数返回大于0的值,用户可以判断哪个套接字句柄返回数据,如果函数返回0表示超时,出错返回-1.需要注意的是,在每次调用完select函数后,需要重新设置fd-set。

延伸阅读

评论