Two way C++ to C# communication using named pipes

后端 未结 2 913
耶瑟儿~
耶瑟儿~ 2020-12-19 05:03

I am trying to have a 2-way communication between a VC++ 6 app and a C# app. I am using named pipes. In my C++ code I can read the message from the C# client but then the se

相关标签:
2条回答
  • 2020-12-19 05:13

    Disposing of a StreamWriter or StreamReader will close the underlying stream.

    Your using statements therefore will be causing the stream to close.

        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);
                }
        }
    

    It should also be noted that because you wrap your stream in a using statement, the commented out pipeStream.Close() function isn't needed.

    0 讨论(0)
  • 2020-12-19 05:27

    Ok, got it working for my application .... thanks Blam !

    Here's the C++ server (run this inside a thread):

    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;
    }
    

    And here's the C# client:

    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);
                }
            }
    

    I'm not actually sending anything from the client to the server because I don't need to ... the key thing in this was the PIPE_WAIT parameter in the CreateNamedPipe() function. This makes the server wait for a client connection.

    0 讨论(0)
提交回复
热议问题