我目前正在创建一个echo服务器,在maxWaitTime处于空闲状态后断开客户端。
我希望程序会阻塞套接字,直到客户端发送数据,但是当我在gdb中运行程序时,它会通过readline上的select和blocks。
我知道retval = 0每当它通过选择并且fd_set袜子进入[256,(31个零)]并且在选择之后,袜子进入[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);
}
`
答案 0 :(得分:4)
正如其他人所评论的,您的代码中存在一些逻辑漏洞。由你自己承认:
我知道retval = 0每当它通过选择并且fd_set袜子进入[256,(31个零)]并且在选择之后,袜子进入[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);
}
}