简体   繁体   English

仅在使用消息模式时,GetLastError()在调用PeekNamedPipe后返回ERROR_BROKEN_PIPE

[英]GetLastError() returns ERROR_BROKEN_PIPE after call to PeekNamedPipe only when using message mode

I can't figure out why this is happening... I have a Named Pipe server and client application. 我无法弄清楚为什么会发生这种情况......我有一个命名管道服务器和客户端应用程序。 Both are in read/write mode and transfer data between each other. 两者都处于读/写模式并在彼此之间传输数据。 The server has two threads, one that reads from the pipe and one that writes to it. 服务器有两个线程,一个从管道读取,另一个写入管道。 While the client is writing a bunch of messages, the server's read thread will exit because it's call to PeekNamedPipe is returning false. 当客户端正在编写一堆消息时,服务器的读取线程将退出,因为它对PeekNamedPipe的调用返回false。 The return value of GetLastError() is ERROR_BROKEN_PIPE. GetLastError()的返回值是ERROR_BROKEN_PIPE。 Neither thread in the server is closing the pipe, and the client is still writing to the pipe, so I don't understand why the pipe is "broken." 服务器中的任何线程都没有关闭管道,客户端仍在写入管道,所以我不明白为什么管道“坏了”。

If I change the server to BYTE mode, then everything works flawlessly. 如果我将服务器更改为BYTE模式,那么一切都可以完美运行。 I am really wanting to use Message mode though so my "messages" do not get grouped together. 我真的想要使用消息模式,所以我的“消息”不能组合在一起。

If I change the client to BYTE mode and the server to Message mode, it works. 如果我将客户端更改为BYTE模式并将服务器更改为消息模式,则可以正常工作。

Call to CreateNamedPipe 调用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);

Call to PeekNamedPipe 致电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
}

You are calling GetLastError() not only when PeekNamedPipe() fails, but also when it succeeds and returns 0 bytes. 您不仅在PeekNamedPipe()失败时调用GetLastError() ,而且在成功并返回0字节时调用GetLastError() You should not be calling GetLastError() in that latter case, as the value will not be meaningful. 在后一种情况下,您不应该调用GetLastError() ,因为该值没有意义。 Use it more like this instead: 使用它更像这样:

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 
} 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM