Здравствуйте.
Пишу клиент для TCP. Задача - приконнектиться к серверу и принимать/получать сообщения. Вот код рабочего потока:
void tcp_client::exec(void)
{
char buffer[MAX_RECV_BUFFER_SIZE];
WSABUF sendBuf, recvBuf;
recvBuf.buf = buffer;
recvBuf.len = MAX_RECV_BUFFER_SIZE;
bool bStop = false;
DWORD bytes_transferred = 0;
int rc, err = 0;
DWORD flags = 0;
DWORD wait_result;
while(!bStop)
{
int recv_result = WSARecv(socket, &recvBuf, 1, NULL, &flags, &hRecvOverlapped, NULL);
int gle = WSAGetLastError();
if(recv_result != 0 && gle != WSA_IO_PENDING)
{
std::cout << "WSARecv failed with error: " << WSAGetLastError() << std::endl;
break;
}
wait_result = WaitForMultipleObjects(3, hArr, FALSE, INFINITE); // hArr - HANDLE hArr[3] = {StopEvent, hRecvOverlapped.hEvent, SendEvent};
switch(wait_result)
{
case WAIT_OBJECT_0: // stop
bStop = true;
break;
case WAIT_OBJECT_0 + 1: // receive
if(!WSAGetOverlappedResult(socket, &hRecvOverlapped, &bytes_transferred, FALSE, &flags))
{
bStop = true;
break;
}
if(bytes_transferred > 0)
{
/* ... */
}
else if(bytes_transferred == 0)
{
!!!
}
break;
case WAIT_OBJECT_0 + 2: // send
/* ... */
default:
break;
}
}
shutdown(socket, SD_BOTH);
closesocket(socket);
socket = NULL;
SetEvent(hStoppedEvt);
}
Проблема собственно в том, что при закрытии сервера (при shutdown и closesocket) в клиенте WSARecv возвращает -1, WSAGetLastError() - WSA_IO_PENDING и событие в hRecvOverlapped в сигнальном состоянии, т.е. WaitForMultipleObjects сразу возвращает 1 -> switch переходит в case receive и так дальше по кругу и бегает, WaitForMultipleObjects не ждет. Вроде при разрыве коннекта WSARecv должен ошибку возвратить, а возвращает WSA_IO_PENDING... Подскажите, пожалуйста, почему так происходит и как с этим бороться? Заранее спасибо за ответы...