Событие FD_CLOSE и ошибка 10035
От: izverg США  
Дата: 12.10.05 03:12
Оценка:
Здравствуйте. У меня возникла проблема с тем что у меня теряется соединение. Кто инициатор разрыва не понимаю. В коде клиента я получаю событие FD_CLOSE. Вот как я создаю сокет и начинаю соединение:

m_hSocket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
u_long nTrue = 1;
ioctlsocket( m_hSocket, FIONBIO, &nTrue );
WSAEventSelect( m_hSocket, m_hSocketEvent, FD_CONNECT | FD_READ | FD_WRITE | FD_CLOSE );

if ( 0 != connect( m_hSocket, (SOCKADDR*)&m_saRemote, sizeof(m_saRemote) ) &&
        WSAGetLastError() != WSAEWOULDBLOCK )
{
   closesocket( m_hSocket );
   m_hSocket = INVALID_SOCKET;
   return FALSE;
}


А так же есть тред который пасёт все события, он выглядит примерно так:

HANDLE hWait[2] = { m_hThreadStop, m_hSocketEvent };
DWORD tConnecting = 0;

while ( DWORD dwEventNum = WaitForMultipleObjects( 2, hWait, FALSE, 5000 ) != WAIT_OBJECT_0 )
{
    if ( INVALID_SOCKET == m_hSocket )
    {
        Connect();
        tConnecting = GetTickCount();
    }
    else
    {
        WSANETWORKEVENTS oEvents;
        ZeroMemory( &oEvents, sizeof(oEvents) );

        WSAEnumNetworkEvents( m_hSocket, m_hSocketEvent, &oEvents );
      DWORD dwWSAError = WSAGetLastError();

        if ( ! m_bConnected )
        {
            if ( oEvents.lNetworkEvents & FD_CONNECT )
            {
                if ( oEvents.iErrorCode[ FD_CONNECT_BIT ] == 0 )
                    m_bConnected = TRUE;
                else
                    Disconnect();
            }
            else
                if ( ( GetTickCount() - tConnecting ) >= 20000 )
                    Disconnect();
        }

        if ( oEvents.lNetworkEvents & FD_CLOSE )
            Disconnect();
    }
}


Так вот, после некоторого простоя без передачи данных (всегда разное время — иногда минута, иногда пятнадцать минут) я получаю FD_CLOSE и WSAGetLastError() равный 10035 (A non-blocking socket operation could not be completed immediately) что, честно говоря, меня сильно озадачивает. Я думал что проблема в том что у меня не бегают данные, попробовал поиграться с SIO_KEEPALIVE_VALS, но это тоже не помогло.

Посоветуйте в чём может быть дело? Почему клиент неожиданно решает что соединение разорвано? :(

Спасибо.
Re: Событие FD_CLOSE и ошибка 10035
От: Roman Pushkin Россия  
Дата: 12.10.05 06:46
Оценка:
Здравствуйте, izverg, Вы писали:

I>Посоветуйте в чём может быть дело? Почему клиент неожиданно решает что соединение разорвано?


К примеру, мой обработчик событий с асинхронными сокетами выглядит так:

case WM_ON_SOCKET:
//...
switch(WSAGETSELECTEVENT(lParam))
{
  case FD_READ:
  //...
  case FD_WRITE:
  //...
  case FD_CLOSE:
  //...
  case FD_CONNECT:
  //...
} // switch...

if(WSAGETSELECTERROR(lParam))
{
  // печатать сообщение об ошибке
  shutdown_socket(...);
}


А это сообщение это вовсе не ошибка, а информация, которая говорит о том, что текущая операция не может завершиться сразу. И оно понятно — сокеты-то асинхронные! Так что можешь игнорировать это сообщение. Попробуй
.
Re[2]: Событие FD_CLOSE и ошибка 10035
От: izverg США  
Дата: 12.10.05 23:15
Оценка:
Здравствуйте, Roman Pushkin, Вы писали:

RP>Здравствуйте, izverg, Вы писали:


I>>Посоветуйте в чём может быть дело? Почему клиент неожиданно решает что соединение разорвано? :(

RP>А это сообщение это вовсе не ошибка, а информация, которая говорит о том, что текущая операция не может завершиться сразу. И оно понятно — сокеты-то асинхронные! Так что можешь игнорировать это сообщение. Попробуй :)
А как Вы понимаете асинхронность события FD_CLOSE ? В общем я попробовал проигнорировать. Это не помогло. В момент когда я в клиенте получил это событие NETSTAT показывает что соединения уже нету. Вообще. В результате сегодняшнего секса было выяснено что это происходит только когда сервер и клиент работают на одном IP. Как следствие я не могу посмотреть сниффером кто первый шлёт FIN пакет чтобы понять кто инициатор разрыва.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.