Здравствуйте. У меня возникла проблема с тем что у меня теряется соединение. Кто инициатор разрыва не понимаю. В коде клиента я получаю событие 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, но это тоже не помогло.
Посоветуйте в чём может быть дело? Почему клиент неожиданно решает что соединение разорвано? :(
Спасибо.
Здравствуйте, 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(...);
}
А это сообщение это вовсе не ошибка, а информация, которая говорит о том, что текущая операция не может завершиться сразу. И оно понятно — сокеты-то асинхронные! Так что можешь игнорировать это сообщение. Попробуй