【问题标题】:Two way C++ to C# communication using named pipes使用命名管道的两种 C++ 到 C# 通信
【发布时间】:2012-05-24 15:22:24
【问题描述】:

我正在尝试在 VC++ 6 应用程序和 C# 应用程序之间进行双向通信。我正在使用命名管道。在我的 C++ 代码中,我可以从 C# 客户端读取消息,但随后服务器“死机”,我必须再次重新启动它。

我想做的是让 C# 应用程序连接到 C++ 应用程序,请求状态,然后 C++ 应用程序关闭并检查状态,然后返回“忙碌”或“空闲”。

我无法将任何内容写回 C# 客户端,因为它说连接已关闭。我注释掉的一些东西是我已经尝试过的。

C++ 代码(作为线程启动)

UINT CNamedPipe::StartNamedPipeServer()
{
LPTSTR lpszPipename = "\\\\.\\pipe\\SAPipe"; 
    HANDLE hPipe; 
    BOOL flg;
    DWORD dwWrite,dwRead;
    char szServerUpdate[200];
    char szClientUpdate[200];

    hPipe = CreateNamedPipe (    lpszPipename, 
                                PIPE_ACCESS_DUPLEX,
                                PIPE_TYPE_MESSAGE | 
                                PIPE_READMODE_MESSAGE | 
                                PIPE_NOWAIT,                    //changed from nowait
                                PIPE_UNLIMITED_INSTANCES,    // max. instances 
                                BUFSIZE,                    // output buffer size 
                                BUFSIZE,                    // input buffer size 
                                PIPE_TIMEOUT,                // client time-out 
                                NULL);                        // no security attribute 

    if (hPipe == INVALID_HANDLE_VALUE) 
        return 0;

    ConnectNamedPipe(hPipe, NULL);

    while(m_bServerActive)  //This seems to work well ....
    {

        //Read from client
        flg = ReadFile(hPipe,szClientUpdate,strlen(szClientUpdate),&dwRead, NULL);

        if(flg) //Read something from the client!!!!
        {
            CString csMsg,csTmp;

            for(int i=0;i<dwRead;i++){
                csTmp.Format("%c",szClientUpdate[i]);
                csMsg += csTmp;
            }


            AfxMessageBox("Client message: " + csMsg);

            strcpy( szServerUpdate,"busy");

            //Write status to Client
            flg = WriteFile(hPipe, szServerUpdate, strlen(szServerUpdate), &dwWrite, NULL);

            EndServer();
            StartServer();
        }

    }

    return 0;

}

C#代码:

public void ThreadStartClient(object obj)
    {
        // Ensure that we only start the client after the server has created the pipe
        ManualResetEvent SyncClientServer = (ManualResetEvent)obj;

        // Only continue after the server was created -- otherwise we just fail badly
        // SyncClientServer.WaitOne();

        using (NamedPipeClientStream pipeStream = new NamedPipeClientStream(".", "SAPipe"))
        {
            // The connect function will indefinately wait for the pipe to become available
            // If that is not acceptable specify a maximum waiting time (in ms)
            pipeStream.Connect();

            //Write from client to server
           using (StreamWriter sw = new StreamWriter(pipeStream))
            {
                sw.WriteLine("What's your status?");
           }

            //Read server reply
            /*using (StreamReader sr = new StreamReader(pipeStream))
            {
                string temp = "";
                temp = sr.ReadLine();   //Pipe is already closed here ... why?

                MessageBox.Show(temp);

            }*/

            //pipeStream.Close();

        }
    }
}

【问题讨论】:

    标签: c# c++ visual-c++ named-pipes


    【解决方案1】:

    处理StreamWriterStreamReader 将关闭底层流。

    因此,您的 using 语句将导致流关闭。

        public void ThreadStartClient(object obj)
        {
                // Ensure that we only start the client after the server has created the pipe
                ManualResetEvent SyncClientServer = (ManualResetEvent)obj;
    
                // Only continue after the server was created -- otherwise we just fail badly
                // SyncClientServer.WaitOne();
    
                using (NamedPipeClientStream pipeStream = new NamedPipeClientStream(".", "SAPipe"))
                {
                    // The connect function will indefinately wait for the pipe to become available
                    // If that is not acceptable specify a maximum waiting time (in ms)
                    pipeStream.Connect();
    
    
                    //Write from client to server
                    StreamWriter sw = new StreamWriter(pipeStream))
                    sw.WriteLine("What's your status?");
    
                    //Read server reply
                    StreamReader sr = new StreamReader(pipeStream)
                    string temp = "";
                    temp = sr.ReadLine();   //Pipe is already closed here ... why?
    
                    MessageBox.Show(temp);
                }
        }
    

    还应注意,由于您将流包装在 using 语句中,因此不需要注释掉的 pipeStream.Close() 函数。

    【讨论】:

    • 谢谢,帮助很大。我将更改我的代码,看看会发生什么。您可能已经猜到了,我是 C# 新手。
    • 没问题,记得点选票下的勾,这样你的支持率会更高!
    【解决方案2】:

    好的,让它适用于我的应用程序......谢谢 Blam!

    这是 C++ 服务器(在线程中运行):

    UINT CNamedPipe::StartNamedPipeServer()
    {
        if(!m_bServerActive)
            return 0;
    
        LPTSTR lpszPipename = "\\\\.\\pipe\\MyPipe"; 
            HANDLE hPipe; 
            BOOL flg;
            DWORD dwWrite,dwRead;
            char szServerUpdate[200];
            char szClientUpdate[200];
    
            hPipe = CreateNamedPipe (    lpszPipename, 
                                        PIPE_ACCESS_DUPLEX,
                                        PIPE_TYPE_MESSAGE | 
                                        PIPE_READMODE_MESSAGE | 
                                        PIPE_WAIT,                  //HAS TO BE THIS
                                        PIPE_UNLIMITED_INSTANCES,    // max. instances 
                                        BUFSIZE,                    // output buffer size 
                                        BUFSIZE,                    // input buffer size 
                                        PIPE_TIMEOUT,                // client time-out 
                                        NULL);                        // no security attribute 
    
            if (hPipe == INVALID_HANDLE_VALUE) 
                return 0;
    
            ConnectNamedPipe(hPipe, NULL);
    
    
            strcpy( szServerUpdate,"busy");
    
            //Write status to Client
            flg = WriteFile(hPipe, szServerUpdate, strlen(szServerUpdate), &dwWrite, NULL);
    
            EndServer();
            StartServer();
    
            return 0;
    }
    

    这是 C# 客户端:

    public void ThreadStartClient(object obj)
            {
                // Ensure that we only start the client after the server has created the pipe
                ManualResetEvent SyncClientServer = (ManualResetEvent)obj;
    
                using (NamedPipeClientStream pipeStream = new NamedPipeClientStream(".", "MyPipe", PipeDirection.InOut))
                {
    
                    // The connect function will indefinately wait for the pipe to become available
                    // If that is not acceptable specify a maximum waiting time (in ms)
                    pipeStream.Connect();
    
                    if (!pipeStream.IsConnected)    //It thinks it's connected but can't read anything ....
                    {
                        MessageBox.Show("Failed to connect ....");
                        return;
                    }
    
                    //Read server reply
                    StreamReader sr = new StreamReader(pipeStream);
    
                    char[] c = new char[200];
    
                    while (sr.Peek() >= 0)
                    {
                        sr.Read(c, 0, c.Length);
                    }
    
                    string s = new string(c);
                    MessageBox.Show(s);
                }
            }
    

    我实际上并没有从客户端向服务器发送任何内容,因为我不需要...其中的关键是 CreateNamedPipe() 函数中的 PIPE_WAIT 参数。这使服务器等待客户端连接。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多