GetLastError () возвращает ERROR_BROKEN_PIPE после вызова PeekNamedPipe только при использовании режима сообщений - PullRequest
3 голосов
/ 15 ноября 2011

Я не могу понять, почему это происходит ... У меня есть сервер Named Pipe и клиентское приложение. Оба находятся в режиме чтения / записи и передают данные друг другу. На сервере есть два потока: один читает из канала, а другой пишет в него. Пока клиент пишет кучу сообщений, поток чтения сервера завершается, поскольку его вызов PeekNamedPipe возвращает false. Возвращаемое значение GetLastError () - ERROR_BROKEN_PIPE. Ни один из потоков на сервере не закрывает канал, а клиент все еще пишет в канал, поэтому я не понимаю, почему канал "сломан".

Если я переключу сервер в режим BYTE, то все будет работать безупречно. Я действительно хочу использовать режим сообщений, поэтому мои "сообщения" не группируются вместе.

Если я переключаю клиента в режим BYTE, а сервер в режим сообщений, он работает.

Позвонить на CreateNamedPipe

hPipe = CreateNamedPipe(
    pszPipeName,
    PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
    PIPE_WAIT | PIPE_READMODE_MESSAGE | PIPE_TYPE_MESSAGE,
    PIPE_UNLIMITED_INSTANCES,
    dwOutBufferSize,
    dwInBufferSize,
    0,
    NULL);

Позвонить на PeekNamedPipe

while( RunningState == DDCMP_STATE_RUNNING )
{
    if( !PeekNamedPipe(hPipe,NULL,NULL,NULL,&dwBytesAvailable,NULL) || !dwBytesAvailable )
        if( GetLastError() == ERROR_BROKEN_PIPE || GetLastError() == ERROR_PIPE_NOT_CONNECTED || GetLastError() == ERROR_INVALID_HANDLE )
            break;
        else
        {
            Sleep( 100 );
            continue;
        }

    //call to ReadFile(hPipe,...) with dwBytesAvailable as size, and then processing of data
}

1 Ответ

2 голосов
/ 15 ноября 2011

Вы вызываете GetLastError() не только при сбое PeekNamedPipe(), но также при успешном завершении и возвращении 0 байтов.Вы не должны вызывать GetLastError() в этом последнем случае, так как значение не будет иметь смысла.Вместо этого используйте больше как это:

while( RunningState == DDCMP_STATE_RUNNING ) 
{ 
    if( !PeekNamedPipe(hPipe, NULL, NULL, NULL, &dwBytesAvailable, NULL) )
    {
        DWORD dwError = GetLastError();

        if( (dwError == ERROR_BROKEN_PIPE) ||
            (dwError == ERROR_PIPE_NOT_CONNECTED) ||
            (dwError == ERROR_INVALID_HANDLE) )
        { 
            break;
        }

        dwBytesAvailable = 0;
    }

    if( !dwBytesAvailable )
    {
        Sleep(100);
        continue;
    }

    //call to ReadFile(hPipe,...) with dwBytesAvailable as size, and then processing of data 
} 
...