select () кажется привязанным к cout / stdout? - PullRequest
0 голосов
/ 14 января 2011

Я использую select (), чтобы выяснить, когда неблокирующее соединение либо подключается, либо подключается, либо не удается подключиться;использование TCP-сокетов в Linux.Мои фактические TCP-соединения подключаются и работают правильно, это просто для определения их статуса.

Странно то, что мой код всегда сначала дает мне то, что я считаю CONNECTIONFAILED .. после cout (любой cout) следующий вызов select () дает мне то, что я считаю CONNECTED .Независимо от того, подключается ли сокет, не имеет значения.

Я проверил, что я использую хорошо выглядящий сокет (в данном случае его int id равен 3, и, как я уже сказал, он отлично работает с реальнымсоединения проверены путем подключения к прослушивающей сети)

Мой код верхнего уровня

while(1)
{
  state = networking.connectionStatus(socketId);
  .. [cout would go here or not, as described above]
  if(state == CONNECTED) { // connected! }
  else .. // connecting, or connection failed code
}

Мой код выбора, работающий на этом неблокирующем сокете, который передается в connectionStatus

myStateType connectionStatus(int socket)
{
  struct timeval tv; 
  tv.tv_sec = 0; tv.tv_usec = 0; // no timeout, immediately return from select()
  fd_set ourFdSet;

  FD_ZERO(&ourFdSet); // zero the set
  FD_SET(socket, &ourFdSet); // put our socket in to this set

  // Switch to figure out if we can write to our fd yet
  switch(select(socket + 1, NULL, &ourFdSet, NULL, &tv))
  {
    case -1: // connection failed, actual error from select()
      return CONNECTIONFAILED;
    break;
    case 0: // no fds ready to write, still connecting?? can someone verify this is true
      return CONNECTING;
    break;
    case 1: // now we have 1 fd ready to write, but look closer..
      // Examine our socket at the socket level for errors.. if < 0 then getsockopt fail
      if(getsockopt(socket, SOL_SOCKET, SO_ERROR, &error, &len) < 0)
        return CONNECTIONFAILED;

      if(error == 0) return CONNECTED;
      if(error == EINPROGRESS) return CONNECTING;
      // otherwise, failure.. (a real error)
      return CONNECTIONFAILED;
      .. end of function ..

Так что же может происходить, когда здесь играет кут?И все ли на правильном пути?Все справочные страницы и источники в Интернете, похоже, согласны ..

Ответы [ 3 ]

3 голосов
/ 14 января 2011

select() возврат -1 не означает, что соединение не установлено - это означает, что select() сама обнаружила ошибку.Вы должны вернуть что-то другое (или, по крайней мере, поставить perror("select") на этом пути).То же самое относится к getsockopt() сбоям.Их добавление поможет отладить проблему.

В остальном все выглядит хорошо - если сокет не доступен для записи (select() возвращает ноль), то попытка подключения все еще продолжается.Несмотря на ваши заверения об обратном, похоже, что ваши файловые дескрипторы перепутаны.

0 голосов
/ 15 января 2011

Абсолютно странно, поэтому для len нужно установить значение sizeof len (вероятно, правильно установлено значение sizeof error, но они одинаковые).

Я не осознавал, что это было прочитано по getockopt, я думал, что это только возвращаемое значение?Возвращение того, что было в ошибке ..

Спасибо за помощь

0 голосов
/ 14 января 2011

Приведенный выше комментарий верен.

Вы установили нулевое время ожидания для своего выбора, чтобы оно немедленно возвращалось.Это успешное возвращаемое значение, однако все FD_SET могут быть оставлены пустыми.

Когда вы получаете 0 с указанным таймаутом, вы должны проверить FD_ISSET на вашем FD_SET.Если он не установлен, то вы знаете, что вы просто отключили тайм-аут выбора, и сокет не готов к записи.Это объясняет ваш CONNECTERROR, я уверен, что getsockopt () в этом состоянии не очень хорошо определен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...