我的socket类已经工作了一段时间了,但是我想用select()添加一个超时。看起来非常直接,但我总是从select()返回0。我甚至删除了select()检查,因此无论select()如何都读取数据并且数据被读取,但select()仍然报告数据不存在。关于如何让select()停止骗我的任何线索?我还将套接字设置为非阻塞。感谢。
代码:
char buf [ MAXRECV + 1 ];
s = "";
memset ( buf, 0, MAXRECV + 1 );
struct timeval tv;
int retval;
fd_set Sockets;
FD_ZERO(&Sockets);
FD_SET(m_sock,&Sockets);
// Print sock int for sainity
std::cout << "\nm_sock:" << m_sock << "\n";
tv.tv_sec = 1;
tv.tv_usec = 0;
retval = select(1, &Sockets, NULL, NULL, &tv);
std::cout << "\nretval is :[" << retval << "]\n\n";
// Check
if (FD_ISSET(m_sock,&Sockets))
std::cout << "\nFD_ISSET(m_sock,&Sockets) is true\n\n";
else
std::cout << "\nFD_ISSET(m_sock,&Sockets) is false\n\n";
// If error occurs
if (retval == -1)
{
perror("select()");
std::cout << "\nERROR IN SELECT()\n";
}
// If data present
else if (retval)
{
std::cout << "\nDATA IS READY TO BE READ\n";
std::cout << "recv ( m_sock, buf, MAXRECV, 0)... m_sock is " << m_sock << "\n";
int status = recv ( m_sock, buf, MAXRECV, 0 );
if ( status == -1 )
{
std::cout << "status == -1 errno == " << errno << " in Socket::recv\n";
return 0;
}
else if ( status == 0 )
{
return 0;
}
else
{
s = buf;
return status;
}
}
// If data not present
else
{
std::cout << "\nDATA WAS NOT READY, TIMEOUT\n";
return 0;
}
答案 0 :(得分:4)
您对select
的来电不正确,正如您已经发现的那样。尽管第一个参数在许多形式的文档中都被命名为nfds
,但实际上它是传递给fd_set
的任何select
所拥有的最大文件描述符号。在这种情况下,由于您只传入一个文件描述符,因此调用应为:
retval = select(m_sock + 1, &Sockets, NULL, NULL, &tv);
如果您有一个任意数量的套接字,您在另一个线程中处理每个套接字,您可能会发现我对this question的回答是更好的方法。
答案 1 :(得分:0)
糟糕。看起来我忘了设置select()的int nfds:
现在工作得很好。