使用C#在同一进程中使用IPC管道

时间:2012-04-16 18:18:23

标签: c# .net ipc pipe

我有两个主题。一个线程读取请求并使用消息队列将其传递给服务器,其他线程从消息队列中读取响应并将其发回。在同一进程中,调用者类方法在管道上写入请求(使用第一个线程共享的服务器管道流),然后使用第二个线程共享的客户端管道流读取响应。这可以使用Java PipeInputStream和PipeOutputStream轻松完成,如下所示。基本上我在C#中寻找等效的以下Java逻辑。我尝试在C#中使用匿名管道失败。

RequestHandlerThread(如上所述的Thread1)

out = new PipedOutputStream();
readPipeIs = new PipedInputStream(out);
readDataIs = new DataInputStream(readPipeIs);
// read data from readDataIs
// Send it to server over message queue
// Share 'out' so that other class method can write to it. 

响应处理程序(如上所述的线程2)

in = new PipedInputStream();
writePipeOs = new PipedOutputStream(in);
writeDataOs = new DataOutputStream(writePipeOs);

// Wait and read from message queue
// write received data to 'writeDataOs'
// Share 'in' so that other class method can read from it. 

我不确定C#管道是否限制在两个进程之间进行通信。所有上述逻辑都处于相同的过程中,只有两个线程与消息服务器通信。

我在两个线程中尝试了一对AnonymousPipeServerStream和AnonymousPipeClientStream对。我共享了用于写入的服务器流和用于通过其他类方法读取的客户端流。

上述逻辑中的任何明显缺陷或选择IPC的任何建议?

添加源代码 这是测试类

class Test
{
    private static byte[] ret;
    private static bool ready;

    Stream outStream;
    Stream inStream;


    private void clientConnReqHandler()
    {
        AnonymousPipeServerStream pipeServer = new
              AnonymousPipeServerStream(PipeDirection.Out);

        outStream = pipeServer;

        string pipeHandle = 
                     pipeServer.GetClientHandleAsString();

        AnonymousPipeClientStream pipeClient =
            new AnonymousPipeClientStream(PipeDirection.In, 
                       pipeHandle);

        pipeServer.DisposeLocalCopyOfClientHandle();

        ready = false;
        BinaryReader binReader = new BinaryReader(pipeClient);
        int mesgSize = binReader.ReadInt32();
        System.Console.WriteLine("Message Lenght To read: " + 
                                  mesgSize);
        byte[] buffer = binReader.ReadBytes(mesgSize);
        System.Console.WriteLine("Message read: " + 
                    buffer.ToString());
        // Simulate some processing 
        Thread.Sleep(5000);
        mesgProcessing(buffer);

    }
    private static void mesgProcessing(byte[] buffer)
    {

        System.Text.UTF8Encoding encoding = new 
                            System.Text.UTF8Encoding();
        byte[] extra = encoding.GetBytes("Echo : ");

        ret = new byte[buffer.Length + extra.Length];
        System.Buffer.BlockCopy(extra, 0, ret, 0, extra.Length);
        System.Buffer.BlockCopy(buffer, 0, ret, extra.Length, 
                                buffer.Length);
        ready = true;
    }


    private void clientConnRespHandler()
    {
        AnonymousPipeServerStream pipeServer = new 
                AnonymousPipeServerStream(PipeDirection.Out);

        string pipeHandle = 
                  pipeServer.GetClientHandleAsString();

        AnonymousPipeClientStream pipeClient =
            new AnonymousPipeClientStream(PipeDirection.In, 
                  pipeHandle);

        inStream = pipeClient;
        pipeServer.DisposeLocalCopyOfClientHandle();

        while (ready)
        {
            BinaryWriter binWriter = new 
                           BinaryWriter(pipeServer);
            binWriter.Write(ret.Length);
            binWriter.Write(ret);
            ready = false;
        }
    }

    public static void Main()
    {
        Test setup = new Test();
        setup.threadTest();

        Test2 threadTest = new Test2();
        // This method will do actuall read and write. 
        threadTest.runTest(setup.inStream, setup.outStream);
    }
    public void threadTest()
    {
        Thread reqHandlerThread = new Thread(new 
                ThreadStart(clientConnReqHandler));
        Thread respHandlerThread = new Thread(new 
               ThreadStart(clientConnRespHandler));

        reqHandlerThread.Start();
        respHandlerThread.Start();

    }
}

执行读/写的类:

class Test2
{

    internal void runTest(System.IO.Stream inStream, 
                  System.IO.Stream outStream)
    {
        BinaryWriter writer = new BinaryWriter(outStream);

        System.Text.UTF8Encoding encoding = new 
                 System.Text.UTF8Encoding();
        byte[] mesg = encoding.GetBytes("Hello World!!!");

        writer.Write(mesg.Length);
        writer.Write(mesg);

        BinaryReader reader = new BinaryReader(inStream);
        int mesgSize = reader.ReadInt32();
        System.Console.WriteLine("Message Lenght To read: " + 
                      mesgSize);
        byte[] buffer = reader.ReadBytes(mesgSize);
        System.Console.WriteLine("Message read: " + 
                    buffer.ToString());
    }
}

感谢

1 个答案:

答案 0 :(得分:0)

行。它在摆脱DisposeLocalCopyOfClientHandle()之后起作用。当然必须修复while循环条件的一些新错误来检查数据是否准备好并从字节数组中正确打印字符串。