使用线程管道通信

时间:2012-08-21 05:51:24

标签: c# ipc named-pipes

我有两个可执行文件: client.exe server.exe

他们使用命名管道相互沟通。当服务器只侦听客户端请求并向客户端发送响应时,它们工作正常。

但现在要求是exes包含客户端管道和服务器管道。所以每个exe包含两个方法:serverpipe()clientpipe()。这些方法在一个线程中,不相互通信。

第一个客户端和服务器正常通信。

Client.EXE:

public static void Main(string[] Args)
{
    PipeClient obj=new PipeClient();
    obj.client();
    Thread startserver = new Thread(new ThreadStart(obj.server));
    startserver.Start();
}

public void client()
{
    int cnt =0;
    while (true)
    {
       System.IO.Pipes.NamedPipeClientStream pipeClient = new System.IO.Pipes.NamedPipeClientStream(".", "\\\\.\\pipe\\SamplePipe1", System.IO.Pipes.PipeDirection.InOut, System.IO.Pipes.PipeOptions.None);

        if (pipeClient.IsConnected != true) { pipeClient.Connect(); }

        StreamReader sr = new StreamReader(pipeClient);
        StreamWriter sw = new StreamWriter(pipeClient);

        string temp;
        temp = sr.ReadLine();

        if (temp == "Waiting")
        {
            try
            {
                cnt++;
                sw.WriteLine("clientSide Message " + cnt);
                sw.Flush();
                Thread.Sleep(10000);

            }
            catch (Exception ex) { throw ex; }
        }
        else
        {

        }
        pipeClient.Close();
    } 

}

public void server()
{
    StreamWriter sw1 = new StreamWriter("C:\\ServerEXE\\serverdataFile0.txt", true);

    System.IO.Pipes.NamedPipeServerStream pipeServer = new System.IO.Pipes.NamedPipeServerStream("\\\\.\\pipe\\SamplePipeSend1", System.IO.Pipes.PipeDirection.InOut, 4);

    sw1 = new StreamWriter("C:\\ServerEXE\\serverdataFile2.txt", true);

    sw1.Close();

    StreamReader sr = new StreamReader(pipeServer);
    StreamWriter sw = new StreamWriter(pipeServer);

    do
    {
        try
        {
            pipeServer.WaitForConnection();
            string test;
            sw.WriteLine("Waiting");
            sw.Flush();
            pipeServer.WaitForPipeDrain();
            test = sr.ReadLine();
            sw1 = new StreamWriter("C:\\ServerEXE\\serverdataFile2.txt",true);
            sw1.WriteLine(test);
            sw1.Close();
        }

        catch (Exception ex)
        { throw ex; }

        finally
        {
            pipeServer.WaitForPipeDrain();
            if (pipeServer.IsConnected) { pipeServer.Disconnect(); }
        }
    } while (true);
}

SERVER.EXE:

public static void Main()
{
    PipeServer obj = new PipeServer();
    obj.server();
    Thread startserver = new Thread(new ThreadStart(obj.client));
    startserver.Start();
}

public void server()
{
    System.IO.Pipes.NamedPipeServerStream pipeServer = new System.IO.Pipes.NamedPipeServerStream("\\\\.\\pipe\\SamplePipe1", System.IO.Pipes.PipeDirection.InOut, 4);

    StreamReader sr = new StreamReader(pipeServer);
    StreamWriter sw = new StreamWriter(pipeServer);

    do
    {
        try
        {
            pipeServer.WaitForConnection();
            string test;
            sw.WriteLine("Waiting");
            sw.Flush();
            pipeServer.WaitForPipeDrain();
            test = sr.ReadLine();
            Console.WriteLine(test);
        }

        catch (Exception ex)
        { throw ex; }

        finally
        {
            pipeServer.WaitForPipeDrain();
            if (pipeServer.IsConnected) { pipeServer.Disconnect(); }
        }
    } while (true);
}

public void client()
{
    int cnt = 0;
    while (true)
    {
        System.IO.Pipes.NamedPipeClientStream pipeClient = new System.IO.Pipes.NamedPipeClientStream(".", "\\\\.\\pipe\\SamplePipeSend1", System.IO.Pipes.PipeDirection.InOut, System.IO.Pipes.PipeOptions.None);

        if (pipeClient.IsConnected != true) { pipeClient.Connect(); }

        StreamReader sr = new StreamReader(pipeClient);
        StreamWriter sw = new StreamWriter(pipeClient);

        string temp;
        temp = sr.ReadLine();

        if (temp == "Waiting")
        {
            try
            {
                cnt++;
                sw.WriteLine("clientSide Message " + cnt);
                sw.Flush();
                Thread.Sleep(10000);

            }
            catch (Exception ex) { throw ex; }
        }
        else
        {
            pipeClient.Close();
        }
    }
}

2 个答案:

答案 0 :(得分:5)

见内联评论:

public static void Main ( string[] Args )
{
    PipeClient obj = new PipeClient ();
    obj.client (); // <-- This has an endless loop and won't return
    // So the following lines  will never be executed!
    Thread startserver = new Thread ( new ThreadStart ( obj.server ) ); 
    startserver.Start ();
}

在进入无限循环之前启动线程:

public static void Main ( string[] Args )
{
    PipeClient obj = new PipeClient ();
    Thread startserver = new Thread ( new ThreadStart ( obj.server ) );
    startserver.Start (); 
    obj.client (); // Thread already running, so it's ok if this is endless
}

当然,这需要在服务器以及客户端exe中完成 -

答案 1 :(得分:0)

这听起来像是权限问题。

要创建全局可访问的命名管道,应用程序需要SeCreateGlobalPrivilege权限。

如果Windows7启用了UAC,并且客户端未在提升模式下运行,则尝试创建全局命名管道(将无提示)将失败。


一些阅读:

Minimum OS Permissions required to create named pipe (WCF)

http://weblogs.thinktecture.com/cweyer/2007/12/dealing-with-os-privilege-issues-in-wcf-named-pipes-scenarios.html

示例主要关注WCF,但在这种情况下,WCF只是命名管道通信之上的一个层,问题的来源是相同的。