C 选择时套接字阻塞和超时

C 选择时套接字阻塞和超时,c,sockets,select,C,Sockets,Select,我目前正在创建一个echo服务器,在空闲的maxWaitTime之后断开客户端的连接 我希望程序在客户端发送数据之前会阻止套接字,但当我在gdb中运行程序时,它会通过读取线上的select和blocks 无论何时通过select,我都知道retval=0,fd_set sock转到[256,(31个零)],在select之后,sock转到[32个零] 在另一个函数中接受连接,并将连接描述符传递给echo函数 如果你能帮我指出正确的方向,或者让我知道如何在一段时间后断开客户的连接,请让我知道 如果

我目前正在创建一个echo服务器,在空闲的maxWaitTime之后断开客户端的连接

我希望程序在客户端发送数据之前会阻止套接字,但当我在gdb中运行程序时,它会通过读取线上的select和blocks

无论何时通过select,我都知道retval=0,fd_set sock转到[256,(31个零)],在select之后,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);

    }

`

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

无论何时通过select,我都知道retval=0,fd_set sock转到[256,(31个零)],在select之后,sock转到[32个零]

这应该是你的一个迹象,有什么地方出了问题。退出
select()
后,套接字不在
fd\u集合中,这意味着套接字尚不可读
retval=0
表示
select()
超时

每次调用
select()
时,不仅要重置
fd\u集
,还要重置
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); 
    } 
}
int opt=3;
setsockopt(sockfd,SOL_SOCKET,SO_RCVLOWAT,&opt,sizeof(opt));
对于(;;)
{ 
timeout.tv_sec=maxWaitTime;
timeout.tv_usec=0;
FD_零和sock;
FD_套件(短袜FD和短袜);
int retval=select(sockfd+1,&sock,NULL,NULL,&timeout);

if(retval)如果这是在POSIX机器上(例如OSX或Linux),那么
select
的第一个参数应该是编号最高的套接字加上一个。在您的情况下
sockfd+1
。另外,我猜您的超时
maxWaitTime
是非零的?请阅读select()的手册页非常小心。3件重要的事情是:1.要选择的第一个参数必须是最大的套接字描述符加上一个2。发生超时时,select返回0。3.在Linux上,超时参数由select()递减-因此,如果您在另一个点上,当前代码最终将以0超时运行,
select
在出错时返回
-1
,仅在超时时返回零,如果套接字已准备就绪,则返回正数(实际上是三组中已准备就绪的套接字数之和).所以你不能只是检查返回值是否为非零的错误。谢谢!这正是我要找的。