【问题标题】:check on socket with select() returns 0 when data is present当数据存在时,使用 select() 检查套接字返回 0
【发布时间】:2012-06-19 14:35:20
【问题描述】:

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

【问题讨论】:

    标签: c++ sockets select


    【解决方案1】:

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

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

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

    【讨论】:

    • 是的,我完全同意,好多了。我现在的设置是处理 2 个套接字,一个同步和一个异步。但我坚决要重写以实现您的方法。
    【解决方案2】:

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

    现在工作得很好。

    【讨论】:

    • 这是错误的,select() 的第一个参数通常不应该是FD_SETSIZE,尤其是对于这段代码。请参阅 user315052 的回答。
    猜你喜欢
    • 2014-08-11
    • 1970-01-01
    • 1970-01-01
    • 2016-03-03
    • 1970-01-01
    • 1970-01-01
    • 2015-01-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多