2

我在使用命名管道在 C# 和 Java 应用程序之间进行通信时遇到稳定性问题。

这是在 C# 中设置命名管道并读取 XML 字符串行的代码。

try
{
    NamedPipeServerStream inStream = new NamedPipeServerStream(inName, PipeDirection.In);
    inStream.WaitForConnection();
    reader = new StreamReader(inStream);
    while (!Stopped && !reader.EndOfStream)
    {
        string xml = reader.ReadLine();
        processXml(xml);
    }
}
catch (Exception e)
{
    log.Error("Error in receiver", e);
}
finally
{
    log.Info("Receiver ended");
}

这里是连接并用Java编写代码

public void connect() throws TransportUnavailableException
{
    try
    {
        File inPipe = new File(inName);
        os = new FileOutputStream(inPipe);
        // Uses JAXB for XML serialization
        marshaller = context.createMarshaller();
    }
    catch (FileNotFoundException e)
    {
        throw new TransportUnavailableException("Named pipe not found: " + inName);
    }
}

public void send(Message message)
{
    marshaller.marshal(message, os);
    os.write('\n');
    os.flush();
}

一切正常。但是许多用户报告崩溃。我在日志中没有看到任何表明管道死亡原因的异常。我只是看到 C# 中的接收线程结束(即日志中的“接收器结束”),之后我在下一次尝试从 Java 发送时收到 IO 异常,并显示消息“句柄无效”。这似乎是随机发生的,但通常在建立连接后的 1 分钟或 2 分钟内发生。当应用程序没有做任何事情时,管道结束消息也会发生,这可能是自上次用户操作以来的几分钟。然后可能需要几分钟才能尝试从 Java 进行下一次写入。

我的应用程序故意关闭管道的所有原因(例如系统其他地方的崩溃)都被记录下来,我从来没有看到这是管道结束的原因,我只是收到读者已经放弃阅读的消息。

  • 管道被杀死,防病毒,防火墙等是否有任何外部原因?
  • 我注意到我没有像大多数示例似乎使用的那样使用 Java 中的 RandomAccessFile。这可能是一个原因吗?

任何帮助/建议表示感谢谢谢!

4

1 回答 1

1

您的服务器端代码只处理一个连接,然后在读取到 EOS 时退出。您需要创建命名管道,循环接受连接,并启动一个新线程来处理每个连接。完成后,您还需要关闭每个连接。

但是,出于几个原因,我会为此使用 TCP 而不是命名管道。

于 2012-12-11T12:57:16.197 回答