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

サーバー側のコードは 1 つの接続のみを処理し、EOS への読み取り時に終了します。名前付きパイプを作成し、接続を受け入れるループを作成し、新しいスレッドを起動して各接続を処理する必要があります。また、終了したら、各接続を閉じる必要があります。

ただし、いくつかの理由から、これには名前付きパイプではなく TCP を使用します。

于 2012-12-11T12:57:16.197 に答える