为什么select()总是在第一次超时后返回0

ter*_*ry 7 c sockets linux

当我使用Linux套接字程序时,我遇到有关select函数的问题.如果客户端在服务器配置的时间间隔内连接服务器端,那么select函数工作正常.如果超时发生,select函数将永远返回0.那时,我调试客户端,发现客户端已连接到服务器.但是select函数仍然返回0.我已经搜索了这个问题,但没有找到任何帮助.有人知道为什么选择那样吗?我的linux版本是RHEL5.4.谢谢您的帮助.

代码如下所示.

static const int maxLog = 10000;

int main()
{
    int servSock;
    signal(SIGPIPE, SIG_IGN);
    if((servSock = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
    {
        printf("socket create fail\n");
        exit(-1);   
    }
    int val = 1;
    if(setsockopt(servSock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val))<0)
    {
        DieWithUserMessage("setsockopt error");
    }

    struct sockaddr_in serverAddr;
    memset(&serverAddr, 0, sizeof(serverAddr));
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    serverAddr.sin_port = htons(22000);

    if(bind(servSock, (struct sockaddr *) &serverAddr, 
                sizeof(serverAddr)) < 0)
    {
        printf("socket bind  fail\n");
        exit(-1);   
    }

    if(listen(servSock, maxLog) < 0)
    {
        printf("listen failed\n");
        exit(-1);
    }   

    fd_set read_set;
    FD_ZERO(&read_set);
    FD_SET(servSock, &read_set);
    int maxfd1 = servSock + 1; 
    std::set<int> fd_readset;

    for(;;){    
        struct timeval tv;
        tv.tv_sec = 5;
        int ret = select(maxfd1, &read_set, NULL, NULL, tv);       
        if(ret == 0)
            continue;

        if(ret < 0)
            DieWithUserMessage("select error");

        if(FD_ISSET(servSock, &read_set))
        {
            struct sockaddr_in clntAddr;
            socklen_t clntAddrlen = sizeof(clntAddr);
            int clntSock = accept(servSock, (struct sockaddr *) &clntAddr, &clntAddrlen);
            if(clntSock < 0)
            {
                printf("accept failed()");
                exit(-1);
            }   

            maxfd1 = 1 +  (servSock>=clntSock? servSock:clntSock);
            FD_SET(clntSock, &read_set );
            fd_readset.insert(clntSock); 
         }

    } 
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*ler 22

" select()"功能是令人沮丧的使用; 你必须在每次调用它之前设置它的参数,因为它会修改它们.您所看到的是如果您不在每次循环周围设置fd_set时会发生什么的演示.