分享

socket编程select函数的使用

 怎么了啊早上 2014-08-18

用户在ADAM-4501上使用TCP/IP方式通讯时,当服务器发送命令时,进行后续动作,但服务器不发命令时,会等待,导致其它操作无法正常执行。recv这类函数是阻塞函数,也就是说没有得到数据是不会返回的,这就造成了一个问题,程序执行到这些函数里面的时候就一直等待,而这个时候如果要有其他的操作根本得不到响应。而select函数就是为了解决这这个问题。它将很多个阻塞函数做成一个集合,只要这些函数中任何一个有数据输入了,它马上返回,然后判断是哪一个有输入,再进行相应的操作。


select模型的中心思想就是利用select函数,实现对I/O的管理。利用select函数,我们可以判断套接字上是否存在数据,或者能否向一个套接字写入数据。利用这个函数可以防止应用程序在一次I/O的绑定调用中进入锁定状态。
select函数原型:
int select(
  __in     int nfds,    //忽略
  __inout  fd_set *readfds,   //检查可读性
  __inout  fd_set *writefds,   //检查可写性
  __inout  fd_set *exceptfds,   //用于例外数据
  __in     const struct timeval *timeout //超时时间,传递NULL会无限期等待下去,0会立刻返回
);


可读性说明:
1.有数据可以读入。
2.连接已经关闭,重设或者中止。
3.加入调用了listen,而且一个连接正在建立,那么accept函数调用会成功。

关于连接已经关闭,重设或者中止的判断:
当一个套接字在调用了select之后具有可读性,那么这个时候我们可以通过调用recv获得数据。如果真的有数据发送过来,那么这个调用会成功。如果是关闭,重设或者中止,那么recv的调用会失败,这个时候通过wsagetlasterror就可以判断连接是否已经中断。


可写性说明:
1.有数据可以发出。
2.如果已完成了对一个非锁定连接调用处理,连接就会成功。

对于可写性的检查,最好放在需要写数据的时候进行检查。如果和可读性放在同一个地方进行检查,那么select很可能每次都会因为可写性检查成功而返回。


例外数据说明:
1.加入已完成了对一个非锁定连接调用的处理,连接尝试就会失败。
2.有带外数据可供读写。


fd_set几个宏的说明:
FD_SETSIZE   定义了fd_set所允许存放套接字的最大个数,默认是64。
FD_CLR(s,*set):从set中删除套接字s。
FD_ISSET(s, *set):检查s是否set集合的一名成员;如答案是肯定的是,则返回TRUE。
FD_SET(s, *set):将套接字s加入集合set。
FDZERO(*set):将set初始化成空集合。


select调用流程:
1)
使用FDZERO宏,初始化自己感兴趣的每一个fd_set。
2) 使用FDSET宏,将套接字句柄分配给自己感兴趣的每个fd_set。
3) 调用select函数,然后等待在指定的fd_set集合中,I/O活动设置好一个或多个套接字句柄。select完成后,会返回在所有fd_set集合中设置的套接字句柄总数,它会修改每个fd_set结构,删除那些不存在待决I/O操作的套接字句柄
4) 根据select的返回值,我们的应用程序便可判断出哪些套接字存在着尚未完成(待决)的I/O操作—具体的方法是使用FD_ISSET宏,对每个fd_set集合进行检查。
5) 知道了每个集合中“待决”的I/O操作之后,对I/O进行处理,然后返回步骤1 ),继续进行select处理。

如下例
int    sockfd;
fd_set fdR;
struct timeval timeout = ..;
...
for(;;) {
       FD_ZERO(&fdR);
       FD_SET(sockfd, &fdR);
       switch (select(sockfd + 1, &fdR, NULL, &timeout)) {
                case -1:
                        error handled by u;
                case 0:
                        timeout hanled by u;
                default:
                        if (FD_ISSET(sockfd)) {
                                now u read orrecv something;


                        }
       }
}


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多