Socket Blocking and Timeout on Select

南笙酒味 提交于 2020-12-26 04:13:08

问题


I am currently creating an echo server that disconnects clients after a maxWaitTime of being in idle.

I was hoping the program would block the socket until the client sent data but when I run the program in gdb it goes through the select and blocks on Readline.

I know retval = 0 whenever it goes through the select and that the fd_set sock goes to [256, (31 zeroes)] and after the select, sock goes to [32 zeroes].

The accepting of the connection happens in another function and the connection descriptor is passed to the echo function.

If you are able to help point me in the right direction or let me know how I can disconnect a client after a certain amount of time please let me know.

If you require any further information please let me know.

Thanks in advance!

    FD_ZERO(&sock);
    FD_SET(sockfd,&sock);

    int opt = 3;

    setsockopt(sockfd, SOL_SOCKET, SO_RCVLOWAT,&opt,sizeof(opt));

    timeout.tv_sec = maxWaitTime;
    timeout.tv_usec = 0;

    for ( ; ; ) {
            FD_SET(sockfd,&sock);

            printf("Set is %d\n",FD_ISSET(sockfd,&sock));

            int retval;
            retval = select(1, &sock, NULL, NULL, &timeout);

            if(retval)
            {
                    quitProgram(number);
            }
            else
            {
            printf("n is %d\n",retval);

            if ( (n = Readline(sockfd, line, MAXLINE)) == 0)
            {
                    return;         /* connection closed by other end */
            }

            Writen(sockfd, line, n);

    }

`


回答1:


As others have commented, you have some logic holes in your code. By your own admission:

I know retval = 0 whenever it goes through the select and that the fd_set sock goes to [256, (31 zeroes)] and after the select, sock goes to [32 zeroes].

That should have been an indication to you that something was going wrong. The socket was not in the fd_set after select() exited, which meant the socket was not readible yet. retval=0 means select() timed out.

You have to reset not only the fd_set every time select() is called, but also the timeval as well. Try this instead:

int opt = 3; 
setsockopt(sockfd, SOL_SOCKET, SO_RCVLOWAT,&opt,sizeof(opt)); 

for ( ; ; )
{ 
    timeout.tv_sec = maxWaitTime; 
    timeout.tv_usec = 0; 

    FD_ZERO(&sock); 
    FD_SET(sockfd,&sock); 

    int retval = select(sockfd+1, &sock, NULL, NULL, &timeout); 
    if (retval <= 0) 
    { 
        quitProgram(number); /* error or connection timed out */
    } 
    else 
    { 
        if ( (n = Readline(sockfd, line, MAXLINE)) <= 0) 
        { 
            return; /* error or connection closed by other end */ 
        } 

        Writen(sockfd, line, n); 
    } 
}


来源:https://stackoverflow.com/questions/12602134/socket-blocking-and-timeout-on-select

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!