C 选择时套接字阻塞和超时
我目前正在创建一个echo服务器,在空闲的maxWaitTime之后断开客户端的连接 我希望程序在客户端发送数据之前会阻止套接字,但当我在gdb中运行程序时,它会通过读取线上的select和blocks 无论何时通过select,我都知道retval=0,fd_set sock转到[256,(31个零)],在select之后,sock转到[32个零] 在另一个函数中接受连接,并将连接描述符传递给echo函数 如果你能帮我指出正确的方向,或者让我知道如何在一段时间后断开客户的连接,请让我知道 如果您需要任何进一步的信息,请告诉我 提前谢谢C 选择时套接字阻塞和超时,c,sockets,select,C,Sockets,Select,我目前正在创建一个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
,仅在超时时返回零,如果套接字已准备就绪,则返回正数(实际上是三组中已准备就绪的套接字数之和).所以你不能只是检查返回值是否为非零的错误。谢谢!这正是我要找的。