System.IO.Exception: Труба повреждена
У меня есть два приложения .NET, которые разговаривают друг с другом по именованному каналу. Все отлично с первого раза, но после того, как первое сообщение отправлено, и сервер снова прослушает, метод WaitForConnection()
выдает сообщение System.IO.Exception
с сообщением Труба.
Почему я получаю это исключение? Это мой первый опыт работы с трубами, но аналогичная модель работала для меня в прошлом с сокетами.
Код ahoy!
Сервер:
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);
}
}
Клиент:
public void sendDownPipe(string str)
{
using (var pipe = new NamedPipeClientStream(".", "pipename", PipeDirection.Out))
{
using (var stream = new StreamWriter(pipe))
{
stream.Write(str);
}
}
}
Первый вызов sendDownPipe получает сервер, чтобы печатать сообщение, которое я отправляю, только отлично, но когда он возвращается назад для повторного прослушивания, он копирует.
Ответы
Ответ 1
Я напишу свой код, который, кажется, работает - мне было любопытно, потому что я никогда ничего не делал с трубами. Я не нашел класс, который вы назвали для серверной части в соответствующем пространстве имен, поэтому здесь код основан на NamedPipeServerStream. Обратный вызов - это только потому, что я не мог беспокоиться о двух проектах.
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();
}
}
И клиент делает это:
using (var pipe = new NamedPipeClientStream(".", "p", PipeDirection.Out))
using (var stream = new StreamWriter(pipe))
{
pipe.Connect();
stream.Write("Hello");
}
Я могу повторить выше блока несколько раз с запущенным сервером, без проблем.
Ответ 2
Проблема для меня произошла, когда я буду называть pipe.WaitForConnection() с сервера, после того как клиент отключится. Решение состоит в том, чтобы поймать IOException и вызвать pipe.Disconnect(), а затем снова вызвать pipe.WaitForConnection():
while (true)
{
try
{
_pipeServer.WaitForConnection();
break;
}
catch (IOException)
{
_pipeServer.Disconnect();
continue;
}
}