7

名前付きパイプを使用して、同じマシン上のサーバーとクライアントプロセス間で通信しようとしています。サーバーはクライアントにメッセージを送信し、クライアントはそれを使って何かをして結果を返し、サーバーは結果を取得することになっています。

サーバーのコードは次のとおりです。

using System;
using System.IO;
using System.IO.Pipes;

class PipeServer
{
    static void Main()
    {
        using (NamedPipeServerStream pipeServer =
            new NamedPipeServerStream("testpipe", PipeDirection.InOut))
        {
            Console.WriteLine("NamedPipeServerStream object created.");

            // Wait for a client to connect
            Console.Write("Waiting for client connection...");
            pipeServer.WaitForConnection();

            Console.WriteLine("Client connected.");
            try
            {
                // Read user input and send that to the client process.
                using (StreamWriter sw = new StreamWriter(pipeServer))
                {
                    sw.AutoFlush = true;
                    Console.Write("Enter text: ");
                    sw.WriteLine(Console.ReadLine());
                }

                pipeServer.WaitForPipeDrain();

                using (StreamReader sr = new StreamReader(pipeServer))
                {
                    // Display the read text to the console 
                    string temp;

                    // Wait for result from the client. 
                    while ((temp = sr.ReadLine()) != null)
                    {
                        Console.WriteLine("[CLIENT] Echo: " + temp);
                    }
                }

            }
            // Catch the IOException that is raised if the pipe is 
            // broken or disconnected.
            catch (IOException e)
            {
                Console.WriteLine("ERROR: {0}", e.Message);
            }
        }
    }
}

クライアントのコードは次のとおりです。

using System;
using System.IO;
using System.IO.Pipes;

class PipeClient
{
    static void Main(string[] args)
    {
        using (NamedPipeClientStream pipeClient =
            new NamedPipeClientStream(".", "testpipe", PipeDirection.InOut))
        {

            // Connect to the pipe or wait until the pipe is available.
            Console.Write("Attempting to connect to pipe...");
            pipeClient.Connect();

            Console.WriteLine("Connected to pipe.");
            Console.WriteLine("There are currently {0} pipe server instances open.",
               pipeClient.NumberOfServerInstances);
            using (StreamReader sr = new StreamReader(pipeClient))
            {
                // Display the read text to the console
                string temp;
                while ((temp = sr.ReadLine()) != null)
                {
                    Console.WriteLine("Received from server: {0}", temp);
                }
            }


            // send the "result" back to the Parent process.
            using (StreamWriter sw = new StreamWriter(pipeClient))
            {
                sw.AutoFlush = true;
                sw.WriteLine("Result");
            }

            pipeClient.WaitForPipeDrain();

        }
        Console.Write("Press Enter to continue...");
        Console.ReadLine();
    }
}

しかし、サーバーコードでは、pipeServer.WaitForPipeDrain(); ObjectDisposedExceptionが発生し、「閉じたパイプにアクセスできません」と表示されます。

sw.AutoFlushをtrueに設定すると、クライアントコードでも同じエラーが発生します。

基本的に、c#でパイプという名前のデュプレックスの例を見つけることができませんでした。それか、匿名パイプの例が必要です。2つのパイプがあり、1つは読み取り用で、もう1つは親プロセスと子プロセスの間の書き込み用です。

前もって感謝します。

4

1 に答える 1

7

問題は、のブロックを使用するStreamWriterことです。これにより、基になるストリーム(ここではパイプ)が閉じられます。そのブロックを使用しない場合は、機能するはずです。

次のことができます。

using (var pipeServer = new NamedPipeServerStream("testpipe", PipeDirection.InOut))
using (var streamReader = new StreamReader(pipeServer))
using (var streamWriter = new StreamWriter(pipeServer))
{
   // ... Your code ..
}

Johannes Eggerが指摘したようにStreamWriter、ストリームをフラッシュするDispose()ので、StreamWriter最初に破棄する必要があります。したがって、破棄する最も内側のオブジェクトにする必要があります。

于 2013-02-12T13:08:16.653 に答える