2010-12-15 108 views
7

我需要我的应用程序的帮助。这是一个响应命令行参数的简单程序。如果应用程序第一次被调用,它会在另一个专用于它的线程上作为管道服务器(阻塞,非重叠)启动,而主线程执行其他操作。现在,用户仍然可以使用相同的应用程序可执行文件和命令行参数来调用应用程序,但由于它不是应用程序的第一个实例,它将使用管道将命令行参数传递给第一个实例,然后杀死它自己。所以,这就像模式中的单身进程 - 术语。Windows命名管道问题:错误代码233替代

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

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(),则客户端被强制断开连接,并且在客户端的下一次尝试中,它们将收到错误。你认为这是原因吗?如果是这样,我怎么断开一个客户端没有发生额外的错误?否则,任何我应该知道做这个工作?花了很多时间搞清楚这一点。

回答

10

您应该处理与管道的另一个服务器端实例上的每个客户端实例的通信,并为每个实例分别使用一个线程。所以,当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 
    } 
} 
+0

这在逻辑上是说你有一个线程不会被连接到(因为每一个做得到线程连接产生一个新的线程),只是保持坐着等待客户连接到它。如何在执行完成后确保该线程正确清理? – 2017-07-25 13:17:17