日期:2014-05-16  浏览次数:20927 次

请教select函数等待超时的问题
先上代码:
C/C++ code

    int select_ret;
    struct timeval timeout = {3,0};
    int maxfd = remote_sock_fd + 1;
    fd_set sel_fds;

    while(!process_exit){

        //asynchronous
        FD_ZERO(&sel_fds);
        FD_SET(remote_sock_fd,&sel_fds);

        printf("Starting select() \n"); // 打印select之前的断点
        select_ret = select(maxfd,&sel_fds,NULL,NULL,&timeout);

        switch(select_ret){
            case 0:
                printf("select() timeout \n");
                break;
            case -1:
                printf("Error occurs when select() \n");
                break;
            default:
                if(FD_ISSET(remote_sock_fd,&sel_fds)){
                    recv_from_remote();
                }
        }




很简单的一段代码,用select判断socket套接字是否有数据读,
问题描述如下:代码里的select超时时间是3秒,测试过程中不向接受段发送任何数据,程序在终端显示如下:

Starting select()
select() timeout
Starting select()
select() timeout
Starting select()
select() timeout
Starting select()
select() timeout
...循环显示

第一次打印“Starting select()” 和 “select() timeout” 之间相差了3秒,和预想的一样;
之后的“Starting select()” 和 “select() timeout”就开始没有时间间隔了,打印出“Starting select()”就立刻执行到“select() timeout”,这就和预想的情况不一样了,为什么之后的select()就没有3妙的间隔了呢?

------解决方案--------------------
timeout变量的值在第一次select以后被系统改变了。。不再是3秒。。。你应该用一个临时变量来传递timeout的值。。作为select的参数。。这样。。每次重新select以前先把那个临时变量的值赋为timeout的值
------解决方案--------------------
select_ret = select(maxfd,&sel_fds,NULL,NULL,&timeout);

select会修改sel_fds 及 timeout 参数
在循环中为这两个参数赋值就可以了