0

我编写了一些使用命名管道将字符串从一个应用程序发送到另一个应用程序的代码。它一次可以正常工作,但是当客户端第二次尝试将其发送到服务器应用程序时,它会在尝试连接到客户端时冻结。

服务器代码是这样的:

static void StartServer()
{
   Task.Factory.StartNew(() =>
   {
      var server = new NamedPipeServerStream("MyPipe");
      server.WaitForConnection();
      StreamReader reader = new StreamReader(server);

      while (true)
      {
         var line = reader.ReadLine();

         if (line != null)
         {
            System.Windows.Forms.MessageBox.Show("Data: : " + line);
         }
      }
   });
}

客户端代码为:

private void Test()
{
    using (var client = new NamedPipeClientStream("MyPipe"))
    {
        client.Connect();
        StreamWriter writer = new StreamWriter(client);

        writer.WriteLine("INCOMING:1234567");
        writer.Flush();
        client.Dispose();
    }
}

通过跟踪代码,我可以看到服务器代码中的循环不断检查正在读取的任何行但没有找到任何行。client.Connect()当第二次调用该Test()方法时,客户端正在挂起。没有引发异常。

谁能看到我哪里出错了?

4

2 回答 2

1

您的服务器保持连接到用于发送第一个字符串的第一个管道实例。

但是,您的客户端在每次测试后都会释放其管道实例,因此第二个测试会创建并尝试连接新的管道实例,但服务器不再侦听,因此 Connect 调用会阻塞等待服务器。

您需要:

  1. 使您的服务器多线程,以便在服务已连接的实例时继续侦听;或者
  2. 重构您的客户端,使其连接一次,然后重用该连接的实例。
于 2013-04-30T11:55:40.073 回答
1

根据@Chris Dickson 的回答,我用以下代码解决了我的问题:

Task.Factory.StartNew(() =>
{
    var server = new NamedPipeServerStream("MyPipe", PipeDirection.InOut, 1, PipeTransmissionMode.Message, PipeOptions.Asynchronous);

    StreamReader reader = new StreamReader(server);    
    Boolean connectedOrWaiting = false;

    while (true)
    {

        if (!connectedOrWaiting)
        {
            server.BeginWaitForConnection((a) => { server.EndWaitForConnection(a); }, null);    
            connectedOrWaiting = true;
        }

        if (server.IsConnected)
        {
            var line = reader.ReadLine();

            if (line != null)
                 System.Windows.Forms.MessageBox.Show("Data: : " + line);

            server.Disconnect();    
            connectedOrWaiting = false;
        }                    
    }
});
于 2013-04-30T14:20:11.783 回答