Linux中select函数学习及实例笔记

上传人:平*** 文档编号:12457854 上传时间:2017-10-19 格式:DOCX 页数:13 大小:56.26KB
返回 下载 相关 举报
Linux中select函数学习及实例笔记_第1页
第1页 / 共13页
Linux中select函数学习及实例笔记_第2页
第2页 / 共13页
Linux中select函数学习及实例笔记_第3页
第3页 / 共13页
Linux中select函数学习及实例笔记_第4页
第4页 / 共13页
Linux中select函数学习及实例笔记_第5页
第5页 / 共13页
点击查看更多>>
资源描述

《Linux中select函数学习及实例笔记》由会员分享,可在线阅读,更多相关《Linux中select函数学习及实例笔记(13页珍藏版)》请在金锄头文库上搜索。

1、Linux 中 select 函数学习及实例笔记Unix中的函数 select和 poll用来,支持 Unix中 I/O复用的功能,在 Unix中I/O模型可以分为以一几种:(1)阻塞 I/O(2)非阻塞 I/O(3)I/O 复用(select 和 poll)(4)信号驱动 I/O(SIGIO)(5)异步 I/O其中,现在比较流行的 I/O模型是阻塞 I/O模型.阻塞 I/O是当应用程序和内核交换数据时,由于内核还没有准备好数据,那么应用程序必须进行阻塞,不能 继续执行,直到内核的数据准备好!应用程序取到数据返回后,阻塞过程结束!但返回的结果也并不一定是正确的!这里只是举一个简单的例子!也许情

2、况会更加的 复杂!非阻塞 I/O,例如在和内核交换数据时,如果内核的数据没有准备好,那么应用程序不会一真等待,会有一个返回信息,以判断是那里出了问题!这样有助于确认是在那个阶段出了问题!I/O复用,我们就可以调用系统调用 select和 poll!在这两个系统调用中的某一个阻塞,而不是真正的阻塞 I/O系统调用!下面主要介绍 I/O复用中的 select函数!select 函数可以指示内核等待多个事件中的任一个发生,仅在一个或多个事件发生,或者等待一个足够的时间后才唤醒进程!select 函数的原型如下:#include #includeint select (int maxfdp1,fd_s

3、et *readset,fd_set * writeset,fd_set excpetset,const struct timeval *timeout);返回值:准备好的描述符的正数目 0-超时 -1-出错!其中最后一个参数是一个结构体的指针,它表示等待内核中的一组描述符任一个准备好需要花费多久的时间!其中 timeval指定了秒数和微秒数。struct timevallong tv_sec;/秒数long tv_usec;/微秒数;将 timeout 设置为空指针时,会永远等待下去,等待固定的时间:如果timeout指向的 timeval中的具体的值时,会等待一个固定的时间,不等待立刻返回

4、,这时 timeval中的 tv_sec和 tv_usec为 0.select有三个可能的返回值。1正常情况下返回就绪的文件描述符个数;2经过了 timeout时长后仍无设备准备好,返回值为 0;3如果 select被某个信号中断,它将返回-1 并设置 errno为 EINTR。4如果出错,返回-1 并设置相应的 errno。EBADF 文件描述词为无效的或该文件已关闭EINTR 此调用被信号所中断EINVAL 参数 n 为负值。ENOMEM 核心内存不足中间的三个参数 readset writeset和 excpetset指定我们要让内核测试读、写、异常条件所需的描述字!函数 select使

5、用描述字集,它一般是一个整型的数组,每个数中的每一位代表一个描述符!系统提供了 4个宏对描述符集进行操作:#include #include /设置文件描述符集 fdset中对应于文件描述符 fd的位void FD_SET(int fd, fd_set *fdset);/清除文件描述符集 fdset中对应于文件描述符 fd的位(设置为 0)void FD_CLR(int fd, fd_set *fdset);/清除文件描述符集 fdset中的所有位(既把所有位都设置为 0)void FD_ZERO(fd_set *fdset);/在调用 select后使用 FD_ISSET来检测文件描述符集

6、fdset中对应于文件描述符 fd的位是否被设置。void FD_ISSET(int fd, fd_set *fdset);例如下面一段代码:fd_set readset;FD_ZERO(&readset);FD_SET(5, &readset);FD_SET(33, &readset);则文件描述符集 readset中对应于文件描述符 6和 33的相应位被置为 1,如图1所示:再执行如下程序后:FD_CLR(5, &readset);则文件描述符集 readset对应于文件描述符 6的相应位被置为 0,如图 2所示: 通常,操作系统通过宏 FD_SETSIZE来声明在一个进程中 select

7、所能操作的文件描述符的最大数目。一般情况下被定义为 1024.一个整数占 4个 字节,既32位,那么就是用包含 32个元素的整数数组来表示文件描述符集。我们可以在头文件中修改这个值来改变 select使用的文件描述符集的大小,但 是需要注意的是:必须重新编译内核才能使修改后的值有效。如果我们对其中的个一不感兴趣的话,可以设置为空指针。如果我们把三个都设为空指针,就实现了一个比 sleep更准确的定时器。注意 select函数的第一个参数 maxfdp1,是所有加入集合的句柄值的最大那个值还要加 1。比如我们的描述符为 1 4 5,那么 maxfdp1就为 6.描述符从 0开始。当我们调用函数时

8、,指定我们关心的描述符集,当返回时,指示那些描述符已经准备好了。怎么样才算准备好呢!下面列出几种情况:下列四个条件中的任何一个满足时,套接口准备好读:(1) 套接口接收缓冲区中的数据字节数大于等于套接口接收缓冲区低潮限度的当前值。可以通过 SO_REVILOAT来设置此低潮限度。(2)连接的读这一半关闭,也就是接收了 FIN的 TCP连接,(3)套接口是一个监听套接口且已完成的连接数为非 0.(4)有一个套接口错误等处理。下列三个条件中的任一个满足时,套接口准备好写:(1) 套接口发送缓冲区的可用空间字节娄大于等于套接口发送缓冲区低潮限度的当前值且或者(i)套接口已连接,或者(ii)套接口不要

9、求连接。(2)连接的写这一半关闭,对这样的套接口写操作将产生信号 SIGPIEP。(3)有一个套接口错误待处理。下面是 select函数的一个例子,主要参考网上的例子,并进行的适当的改变!并增加了客户端的程序。修改不 fdi数组,可是实现动态的管理,也解决了,当一个客户不断的断开再连接时,服务器也断开的情况。网址参考如下:http:/ select函数可以以非阻塞的方式和多个 socket通信。程序只是演示 select函数的使用,即使某个连接关闭以后也不会修改当前连接数,连接数达到最大值后会终止程序。1. 程序使用了一个数组 fd,通信开始后把需要通信的多个 socket描述符都放入此数组2

10、. 首先生成一个叫 sock_fd的 socket描述符,用于监听端口。3. 将 sock_fd和数组 fd中不为 0的描述符放入 select将检查的集合fdsr。4. 处理 fdsr中可以接收数据的连接。如果是 sock_fd,表明有新连接加入,将新加入连接的 socket描述符放置到 fd。 */ / select_server.c#include #include #include #include #include #include #include #include #include #include #define MYPORT 1234 /连接时使用的端口#define MAX

11、CLINE 5 /连接队列中的个数#define BUF_SIZE 200int fdMAXCLINE; /连接的 fdint conn_amount; /当前的连接数void showclient()int i;printf(client amount:%dn,conn_amount);for(i=0;i maxsock)maxsock = new_fd;elseprintf(max connections arrive ,exitn);send(new_fd,bye,4,0);close(new_fd); continue;showclient();for(i=0;i#include #i

12、nclude #include #include #include #include #include #include #define MAXDATASIZE 100#define SERVPORT 1234#define MAXLINE 1024int main(int argc,char *argv)int sockfd,sendbytes;/ char sendMAXLINE;char sendMAXLINE;char bufMAXDATASIZE;struct hostent *host;struct sockaddr_in serv_addr;if(argc h_addr);bzero(&(serv_addr.sin_zero),8);if(connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(struct sockaddr) =-1)perror(connect n);exit(1);while(fgets(send,1024,stdin)!=NULL)if(sendbytes = write(sockfd,send,100) =-1)perror(send error n);exit(1);close(sockfd);

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 中学教育 > 试题/考题

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号