Моя петля неправильная? Могу ли я неправильно использовать ReadFile () и порт завершения ввода-вывода?

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

Сначала коды:

сервер: http://pastebin.com/XxeXdunC

и клиент: http://pastebin.com/fbCH2By8

Проблема в сервере (я могу улучшить клиента, но сделаю это, когда сервер заработает).

Я использую порт завершения ввода-вывода следующим образом: в основном, я запускаю поток, в котором вызываю ReadFile (). Если он возвращает TRUE, я получаю все данные, если он возвращает FALSE, а ошибка ERROR_IO_PENDING, я жду с GetQueuedCompletionStatus ().

Странно то, что, даже если я прочитаю все данные, последний вызов ReadFile () завершается неудачно, и возникает ошибка ERROR_IO_PENDING.

Поток, в котором я вызываю ReadFile (), - это начало 64-й строки серверного кода.

Клиент отправляет 24 байта (строка «salut, c'est le client!»), А буфер ReadFile () имеет длину 5 байтов (чтобы проверить, как мой сервер обрабатывает данные, размер которых превышает размер буфера Readfile ()).

Результат:

waiting for client...
WaitForMultipleObjects : 0
client connected (1)
ReadFile 1 msg (5 -> 05) : salut
ReadFile 2 msg (5 -> 10) : salut, c'e
ReadFile 2 msg (5 -> 15) : salut, c'est le
ReadFile 2 msg (5 -> 20) : salut, c'est le clie
ReadFile 2 msg (4 -> 24) : salut, c'est le client !
ReadFile2: ERROR_IO_PENDING
GQCIOS 0 255 003D3A18
ReadFile3: ERROR_IO_PENDING
ReadFile1: ERROR_IO_PENDING
GQCIOS 5 255 003D3A2C
ReadFile3: ERROR_IO_PENDING
ReadFile1: ERROR_IO_PENDING
GQCIOS 5 255 003D3A2C
ReadFile3: ERROR_IO_PENDING
ReadFile1: ERROR_IO_PENDING
GQCIOS 5 255 003D3A2C
ReadFile3: ERROR_IO_PENDING
ReadFile1: ERROR_IO_PENDING
GQCIOS 5 255 003D3A2C
ReadFile3: ERROR_IO_PENDING
ReadFile1: ERROR_IO_PENDING
GQCIOS 4 255 003D3A2C
ReadFile3: ERROR_IO_PENDING
ReadFile1: ERROR_IO_PENDING

Я не понимаю, что даже если я прочитаю все данные, ReadFile () по-прежнему возвращает ожидающую операцию (это сообщение об ошибке «ReadFile2: ERROR_IO_PENDING» после последнего вывода «msg»)

Моя петля неправильная? Могу ли я неправильно использовать ReadFile () / GetQueuedCompletionStatus ()?

Спасибо


person vtorri    schedule 08.04.2011    source источник
comment
Проблема вроде в режиме трубы. Мне нужно использовать режим сообщений (клиент и сервер), но это не помогает: первый вызов ReadFile () не выполняется, количество прочитанных байтов равно 0, а ошибка - ERROR_MORE_DATA. Хотя наличие такой ошибки является нормальным явлением, где хранятся первые 5 байтов?   -  person vtorri    schedule 12.04.2011


Ответы (1)


Где ваша функция, связанная с записью? кажется, что ваш код находится в неправильном порядке. В подпрограмме _read_data_cb сначала должен быть вызван GetQueuedCompletionStatus, затем, в зависимости от параметра lpOverlapped, полученные данные должны быть готовы в буфере, который вы указали в функции ReadFile. Поскольку вы вызываете Readfile, не проверяя, является ли OVERLAPPED перекрывающейся структурой для контекста отправки или контекста recv, вы не получаете ожидаемого результата. Следующий код должен прояснить ситуацию:

while(TRUE)
{
    bReturnValue=GetQueuedCompletionStatus(pIOCPServer->m_pIOCP, &dwBytesTransferred,(DWORD *)pClient,reinterpret_cast<LPOVERLAPPED*>(&pOverlapped),INFINITE);
    if(!bReturnValue)
    {
        if(NULL==pOverlapped)
            continue;
        else
            break;
    }
    else
    {
        if(pOverlapped==NULL)
            continue;
    }
    if(dwBytesTransferred==0)
        break;
    if(lpOverlapped==&(pClient->m_pRecvContext->overlapped))
        pClient->handleRecvEvent(dwBytesTransferred)
    else if(lpOverlapped==&(pClient->m_pSendContext->overlapped))
        pClient->handleSendEvent(dwBytesTransferred)
}
...
person JosephH    schedule 22.05.2011