4

我的套接字类已经工作了一段时间,但我想使用 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;
}
4

2 回答 2

4

select正如您已经发现的那样,您的呼叫不正确。尽管第一个参数nfds在许多形式的文档中都被命名,但它实际上比任何fd_set传递给select. 在这种情况下,由于您只传递一个文件描述符,因此调用应该是:

retval = select(m_sock + 1, &Sockets, NULL, NULL, &tv);

如果您有任意数量的套接字,您在不同的线程中处理每个套接字,您可能会发现我对这个问题的回答是一种更好的方法。

于 2012-06-19T15:36:34.617 回答
0

哎呀。看起来我忘了设置 select() 的 int nfds:

现在工作得很好。

于 2012-06-19T14:55:08.623 回答