Windows命名管道问题:错误代码233交替显示

时间:2010-12-15 15:42:44

标签: named-pipes

我正在制作我的应用程序需要帮助。这是一个响应命令行参数的简单程序。如果第一次调用该应用程序,它将在另一个专用于它的线程上作为管道服务器(阻塞,非重叠)启动,而主线程执行其他操作。现在,用户仍然可以使用相同的应用程序可执行文件和命令行参数调用应用程序,但由于它不是应用程序的第一个实例,因此它使用管道将命令行参数传递给第一个实例,然后杀死自身。所以,它就像模式中的单例过程。

理想情况下,它应该是这样的:

app.exe "first"    // starts app.exe as a pipe server and prints "first"
app.exe "second"   // client process causes server instance to print "second"
app.exe "third"    // client process causes server instance to print "third"
app.exe "fourth"   // client process causes server instance to print "fourth"
app.exe "fifth"    // client process causes server instance to print "fifth"
app.exe -quit      // client process causes server instance to terminate.

现在,我唯一的问题是,当我执行上述操作时会发生这种情况:

app.exe "first"    // starts app.exe as a pipe server and prints "first"
app.exe "second"   // client process returns a GetLastError code of 233
app.exe "third"    // client process causes server instance to print "third"
app.exe "fourth"   // client process returns a GetLastError code of 233
app.exe "fifth"    // client process causes server instance to print "fifth"
app.exe -quit      // client process returns a GetLastError code of 233

我的管道服务器代码是这样的(伪代码):

CreateNamedPipe();
// Code below now runs on a separate thread...
while( !Quit )
{
    if( ConnectNamedPipe() is successful )
    {
        if( PeekNamedPipe() has a message )
        {
            ReadFile();
            ProcessReceivedMessage();
        }
        FileFlushBuffers();
        DisconnectNamedPipe();
    }
}
CloseHandle( the pipe );

我的客户端版本是这样的(伪代码):

if( WaitNamedPipe( FOREVER ) != 0 )
{
    GetParametersAndFormAMessage();
    CreateFile();
    WriteFile(); // Sends message to the pipe server
}
CloseHandle();

根据MSDN,如果服务器使用DisconnectNamedPipe(),则强制客户端断开连接,并且在客户端的下一次尝试时,它们将收到错误。你认为这是原因吗?如果是这样,如何在没有发生额外错误的情况下断开客户端连接?否则,我应该知道的任何事情使这项工作?花了很多时间搞清楚这一点。

1 个答案:

答案 0 :(得分:11)

您应该在管道的不同服务器端实例上处理与每个客户端实例的通信,每个实例使用一个单独的线程。因此,当ConnectNamedPipe()返回时,会立即生成一个新的侦听器线程以等待下一个客户端,然后再处理刚刚连接的客户端的消息。

然后,每个客户端将通过新创建的管道实例进行通话,您将看不到ERROR_PIPE_NOT_CONNECTED错误。

即。 psuedo-code是这样的:

Main Thread
{
    CreateListenerThread();
    WaitForQuitEvent();
}

ListenerThread
{
    ConnectNamedPipe();
    if (no error)
    {
        CreateListenerThread();
        if( PeekNamedPipe() has a message )
        {
            ReadFile();
            ProcessReceivedMessage(); // if -quit signal quit event
        }
        FileFlushBuffers();
        DisconnectNamedPipe();
        CloseHandle();
    }
    else
    {
        // handle/report error
    }
}