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いずれかが保持する最大のファイル記述子番号よりも 1 つ多くなっています。この場合、1 つのファイル記述子のみを渡すため、呼び出しは次のようになります。fd_setselect

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 に答える