只有在使用消息模式时,GetLastError()才会在调用PeekNamedPipe后返回ERROR_BROKEN_P



我不明白为什么会发生这种情况。。。我有一个命名管道服务器和客户端应用程序。两者都处于读/写模式,并在彼此之间传输数据。服务器有两个线程,一个从管道读取,另一个向管道写入。当客户端写入一堆消息时,服务器的读取线程将退出,因为它对PeekNamedPipe的调用返回false。GetLastError((的返回值为ERROR_BROKEN_PIPE。服务器中的两个线程都没有关闭管道,客户端仍在向管道写入,所以我不明白为什么管道"断了">

如果我将服务器更改为BYTE模式,那么一切都可以完美工作。不过,我真的很想使用消息模式,这样我的"消息"就不会被分组在一起了。

如果我将客户端更改为BYTE模式,将服务器更改为Message模式,它就会工作

调用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
}

您不仅在PeekNamedPipe()失败时调用GetLastError(),而且在它成功并返回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 
} 

最新更新