Why select () always returns 0 after the first timeout

I have a problem with the select function when I was working in the Linux socket program. The selection function worked fine, as the manual page says that the client connected the server part in the time interval configured by the server. If a timeout occurs, the select function will return 0 forever. At that time, I am debugging the client and discover that the client has connected to the server. But the select function still returns 0. I have a search for this problem, but I have not found anything useful. Can anyone know why the choice made this? My version of Linux is RHEL5.4. Thank you for your help.

Below is the code.

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); 
         }

    } 
}
+5
source share
5 answers

'select()' ; , , . , , - , , fd_set (s) .

+19

- fd_set select(2).

- Linux epoll(4). , , , . , . epoll , , .

- BSD kqueue(2), Solaris /dev/poll.

: . Stevens UnP: accept.

+3

FD_SET . - FDs , select FD_SET.

, FD_SETSIZE ( /usr/include/sys/select.h).

:)

+1

, reset timeval .

+1

. select(), . .

FD_ZERO(&read_set);
FD_SET(servSock, &read_set);
0

All Articles