2009-05-21 17 views
16

Tengo dos aplicaciones .NET que se comunican entre sí por una tubería con nombre. Todo está bien la primera vez, pero después de que se envía el primer mensaje, y el servidor va a volver a escuchar, el método WaitForConnection() arroja un System.IO.Exception con el mensaje El tubo está roto.
¿Por qué recibo esta excepción aquí? Esta es la primera vez que trabajo con tuberías, pero un patrón similar me ha funcionado en el pasado con conectores.System.IO.Exception: Pipe está roto

Code ahoy!
Servidor:

using System.IO.Pipes; 

static void main() 
{ 
    var pipe = new NamedPipeServerStream("pipename", PipeDirection.In); 
    while (true) 
    { 
     pipe.Listen(); 
     string str = new StreamReader(pipe).ReadToEnd(); 
     Console.Write("{0}", str); 
    } 
} 

Cliente:

public void sendDownPipe(string str) 
{ 
    using (var pipe = new NamedPipeClientStream(".", "pipename", PipeDirection.Out)) 
    { 
     using (var stream = new StreamWriter(pipe)) 
     { 
      stream.Write(str); 
     } 
    } 
} 

La primera llamada a sendDownPipe obtiene el servidor para imprimir el mensaje que envío muy bien, pero cuando se vuelve de nuevo a escuchar de nuevo, se hace caca.

+0

Creo que la razón por la que está teniendo este problema se debe a la línea de "nuevo StreamReader (pipa) ". El alcance del lector de flujo creado es el primer ciclo while y luego se vuelve a crear. Sin embargo, el comportamiento de los lectores de flujo es cerrar la secuencia que envuelven; por lo tanto, una vez que esté fuera del alcance, cerrará la transmisión de canalización. Puede intentar mover su declaración fuera del ciclo while y verificar (P.S: No lo intenté personalmente si el código funciona si lo hace - solo quería agregar un comentario en lugar de responder) – user3141326

Respuesta

16

Voy a publicar mi código que parece funcionar - Tenía curiosidad ya que nunca hice nada con las tuberías. No encontré la clase que nombre para el lado del servidor en el espacio de nombre relevante, así que aquí está el código basado en el NamedPipeServerStream. La devolución de llamada es solo porque no me molestan dos proyectos.

NamedPipeServerStream s = new NamedPipeServerStream("p", PipeDirection.In); 
Action<NamedPipeServerStream> a = callBack; 
a.BeginInvoke(s, ar => { }, null); 
... 
private void callBack(NamedPipeServerStream pipe) 
{ 
    while (true) 
    { 
    pipe.WaitForConnection(); 
    StreamReader sr = new StreamReader(pipe); 
    Console.WriteLine(sr.ReadToEnd()); 
    pipe.Disconnect(); 
    } 
} 

y el cliente hace esto:

using (var pipe = new NamedPipeClientStream(".", "p", PipeDirection.Out)) 
using (var stream = new StreamWriter(pipe)) 
{ 
    pipe.Connect(); 
    stream.Write("Hello"); 
} 

Me puede repetir por encima del bloque múltiples veces con el servidor en funcionamiento, no hay problema.

+0

Eso fue lo que hizo el truco. Supongo que no hay desconexión implícita cuando un cliente se cae del otro lado. Gracias. –

+0

Eso me ayudó también. ¡Gracias por la gran respuesta! –

+1

Esto me da un error de que la tubería no está conectada en esta línea: 'using (var stream = new StreamWriter (pipe))' – eliah

5

El problema para mí ha ocurrido cuando llamé a pipe.WaitForConnection() desde el servidor, después de que el cliente se desconectara. La solución es coger el IOException y llame pipe.Disconnect(), y luego llamar a pipe.WaitForConnection() de nuevo:

while (true) 
{ 
    try 
    { 
     _pipeServer.WaitForConnection(); 
     break; 
    } 
    catch (IOException) 
    { 
     _pipeServer.Disconnect(); 
     continue; 
    }    
}