Windows 命名管道问题:错误代码 233 交替出现

发布于 2024-10-07 22:44:06 字数 1974 浏览 3 评论 0原文

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

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

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(),客户端将被强制断开连接,并且在客户端下次尝试时,它们将收到错误。你认为是这个原因吗?如果是这样,我如何断开客户端连接而不发生额外的错误?否则,我应该知道什么才能使这项工作成功???花了很多时间来解决这个问题。

I need help on my application I am making. It's a simple program that responds to command line parameters. If the application is invoked for the first time, it starts up as a pipe server (blocking, non-overlapped) on another thread devoted to it, while the main thread does something else. Now, the user can still invoke the application using the same application executable and command line parameters but since its not the first instance of the application, it passes the command line parameters to the first instance using the pipe, then kills the itself. So, it's like a singleton process in patterns-lingo.

Ideally, it should be like this:

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.

Now, my only problem is, when I do the above lines this happens:

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

My pipe server code goes something like this (pseudo code):

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 );

My client version goes like this (pseudo code):

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

According to MSDN, if the server uses DisconnectNamedPipe(), the client is forced disconnected and on the next attempt of the client, they will get an error. Do you think that's the reason? If so, how do I disconnect a client without that extra error happening? Otherwise, anything I should know to make this work??? Spent a lot of hours figuring this out.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

娇纵 2024-10-14 22:44:06

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

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

即伪代码如下:

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

You should handle communication with each client instance on a different server-side instance of the pipe, using a separate thread for each. So, when ConnectNamedPipe() returns, immediately spawn a new listener thread to wait for the next client, before processing the message from the client which just connected.

Each client will then be talking via a freshly created instance of the pipe, and you won't see the ERROR_PIPE_NOT_CONNECTED errors.

i.e. psuedo-code something like this:

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
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文