套接字阻塞和选择超时

问题描述 投票:0回答:1

我目前正在创建一个回显服务器,它会在空闲 maxWaitTime 后断开客户端连接。

我希望程序会阻塞套接字,直到客户端发送数据,但是当我在 gdb 中运行该程序时,它会通过 select 并阻塞 Readline。

我知道 retval = 0 每当它通过选择并且 fd_set sock 转到 [256, (31 个零)] 并且在选择之后,sock 转到 [32 个零]。

连接的接受发生在另一个函数中,并且连接描述符被传递给 echo 函数。

如果您能够帮助我指明正确的方向,或者让我知道如何在一段时间后断开客户端连接,请告诉我。

如果您需要任何进一步的信息,请告诉我。

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

    }
c sockets posix-select
1个回答
7
投票

正如其他人评论的那样,您的代码中存在一些逻辑漏洞。您自己承认:

我知道 retval = 0 每当它通过选择并且 fd_set sock 转到 [256, (31 个零)] 并且在选择之后,sock 转到 [32 个零]。

这应该向您表明出现了问题。

fd_set
退出后,套接字不在
select()
中,这意味着套接字尚不可读。
retval=0
表示
select()
超时。

每次调用

fd_set
时,您不仅必须重置
select()
,还必须重置
timeval
。试试这个:

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); 
    } 
}
© www.soinside.com 2019 - 2024. All rights reserved.