Ошибка TCP Connect 115 Выполняется операция В чем причина?

Мое приложение создает TCP-соединение, оно работает нормально. Но в одной сети сервер имеет много IP, скажем

  • 174.X.X.X
  • 54.x.x.x нравится это

При вызове TCP соединение (неблокирующее с тайм-аутом 60 секунд) к IP 174.X.X.X всегда успешно. Но TCP-соединение с тем же сервером с ip 54.x.x.x не работает (в большинстве случаев) с ошибкой 115 в процессе выполнения операции measn.

Не могли бы вы объяснить мне, какова возможная причина ошибки 115?

ОС: линукс

Мой код подключения TCP приведен ниже.

tcp_connect(......)
{

  int iValOpt = 0;  
  int iLength= 0;

  fcnt((int)(long)SockID,F_SETFL_O_NONBLOCK);

  ret = connect (sockID,(struct sockaddr*)pstSockAdr,uiSockLen);

  if (ret < 0)
  {

        if (errno == EINPROGRESS)
        {
                stTv.tv_sec = 60;
                stTv.tv_usec = 0;
                FD_ZERO(&write_fd);
                FD_SET(sockID,&write_fd);

                iLength = sizeof(int);

                if (0 < select (sockID+1) , NULL,&write_fd,NULL,&stTv);

                {
                        if(0 > getsockopt(sockID,SOL_SOCKET,SO_ERROR,(void*)(&iValOpt),&iLength))
                        {
                                return -1
                        }

                        if (0 != iValOpt)
                        {
                                return -1;
                        }


                        return success;
                }

                else
                {
                        return -1;
                }   

        }
        else
        {
                return -1;
        }
    }

   return success;

}

person Syed Shamsheer    schedule 18.04.2012    source источник
comment
Что произойдет, если вы попытаетесь подключиться по телнету к IP-адресу 54.x.x.x без использования вашего приложения? Такое же поведение?   -  person Anders Lindahl    schedule 18.04.2012
comment
нет, ручная шпаклевка работает нормально   -  person Syed Shamsheer    schedule 18.04.2012
comment
«Неблокирующий с тайм-аутом» — это противоречие в терминах.   -  person user207421    schedule 19.04.2012


Ответы (2)


На основании вашей информации:

  • Вы пытаетесь сделать от connect() до 54.x.x.x
  • Сокет non-blocking
  • Время ожидания соединения 60 sec

Во-первых, если вы посмотрите на свой /usr/include/asm-generic/errno.h, вы увидите следующее:

#define EINPROGRESS     115     /* Operation now in progress */

Это означает, что существующая операция над сокетом выполняется. Поскольку вы сказали, что делаете вызов connect(), давайте сделаем man connect:

EINPROGRESS

The socket is nonblocking and the connection cannot be completed 
immediately. It is possible to select(2) or poll(2) for completion by
selecting the socket for writing. After select(2) indicates
writability, use getsockopt(2) to read the SO_ERROR option at level
SOL_SOCKET to determine whether connect() completed successfully
(SO_ERROR is zero) or unsuccessfully (SO_ERROR is one of the usual
error codes listed here, explaining the reason for the failure).

Таким образом, лучше всего предположить, что трехстороннее рукопожатие TCP (ваш connect() вызов на 54.x.x.x IP-адрес) занимает больше времени, чем ожидалось. Поскольку операция connect() уже выполняется, любая последующая операция над сокетом приводит к коду ошибки EINPROGRESS. Как предлагается на странице руководства, попробуйте использовать select() или poll(), чтобы проверить, готов ли ваш сокет к использованию (для выполнения вызовов read() или write()).

Вы можете точно определить, что препятствует завершению вашего TCP-рукопожатия, перехватив и проанализировав трафик к/от вашей собственной машины и 54.x.x.x. Лучший инструмент, который поможет вам в этом, называется WireShark. Удачи.

Трехстороннее рукопожатие TCP

person gsbabil    schedule 18.04.2012
comment
Я добавил свой код выше, не могли бы вы проверить возможные ошибки? приведенный выше код отлично работает в моей сети, возможно, из-за моей сетевой неблокирующей ошибки EINPROGRESS никогда не происходит - person Syed Shamsheer; 18.04.2012
comment
@ user1340512: Попробуйте опубликовать чистую и полную версию кода, чтобы можно было протестировать. - person gsbabil; 19.04.2012
comment
Спасибо за ваш ответ, я не могу разместить здесь весь код, но я вставил только код, в котором возвращается ошибка. Код отлично работает в нашей сети (может быть, потому, что в нашей сети никогда не возникает неблокирующая ошибка, и подключение всегда выполняется успешно). Мне нужно знать, если EINPROGRESS errno установлен выше кода, работает нормально или до 60 с код abvoe может вернуть -1 - person Syed Shamsheer; 19.04.2012

Похоже, это поведение connect():

Если соединение не может быть установлено немедленно и для дескриптора файла для сокета установлено значение O_NONBLOCK, функция connect() завершится ошибкой и установит для errno значение [EINPROGRESS], но запрос на соединение не будет прерван, и соединение будет установлено асинхронно. Последующие вызовы connect() для того же сокета до того, как соединение будет установлено, завершатся ошибкой и присвоят errno значение [EALREADY].

person Anders Lindahl    schedule 18.04.2012
comment
Мое приложение - SFTP, пользователь создает множество подключений к одному серверу с одним и тем же портом 22. - person Syed Shamsheer; 18.04.2012