2010-12-15 15 views
7

Necesito ayuda en mi solicitud que estoy haciendo. Es un programa simple que responde a los parámetros de línea de comando. Si la aplicación se invoca por primera vez, se inicia como un servidor de canalización (bloqueo, no superpuesto) en otro hilo dedicado a él, mientras que el hilo principal hace algo más. Ahora, el usuario puede invocar la aplicación utilizando el mismo ejecutable de aplicación y los mismos parámetros de línea de comando, pero como no es la primera instancia de la aplicación, pasa los parámetros de la línea de comando a la primera instancia utilizando el conducto y luego lo destruye. Entonces, es como un proceso singleton en patrones-jerga.Problema de Windows Named Pipe: Código de error 233 alternas

Idealmente, debería ser así:

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. 

Ahora, mi único problema es que cuando hago las líneas anteriores esto sucede:

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 

Mi código de servidor de canalización es algo como esto (pseudocódigo):

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

Mi versión del cliente es la siguiente (pseudo código):

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

De acuerdo con MSDN, si el servidor utiliza DisconnectNamedPipe(), el cliente se desconecta forzosamente y en el siguiente intento del cliente, recibirá un error. ¿Crees que esa es la razón? Si es así, ¿cómo desconecto un cliente sin que ocurra ese error adicional? De lo contrario, cualquier cosa que deba saber para que esto funcione? Pasé muchas horas averiguando esto.

Respuesta

10

Debe gestionar la comunicación con cada instancia de cliente en una instancia del lado del servidor diferente de la tubería, utilizando un hilo separado para cada una. Por lo tanto, cuando devuelve ConnectNamedPipe(), genera inmediatamente un nuevo hilo de escucha para esperar al siguiente cliente, antes de procesar el mensaje del cliente que acaba de conectarse.

Cada cliente estará hablando a través de una instancia recién creada de la tubería, y no verá los errores ERROR_PIPE_NOT_CONNECTED.

es decir pseudo-código de algo como esto:

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

Esto lógicamente significa que usted tiene un hilo que no consigue conectarse a (porque cada hilo que se pone conectado a genera un nuevo hilo) y justo se queda sentado esperando que un cliente se conecte. ¿Cómo se asegura de que ese hilo se limpia correctamente una vez que finaliza la ejecución? –

Cuestiones relacionadas