C++ <-> C# 命名管道通信

C++ <-> C# Named Pipe Communication

本文关键字:管道 通信 gt lt C++      更新时间:2023-10-16

使用命名管道在窗口上实现IPC。

C# 命名管道服务器和C++命名管道客户端。将数据从C++客户端发送到 C# 服务器时丢失第一个字符。

例如,如果从C++客户端发送"这是测试消息",服务器将收到"他的是测试消息"。下面是启示代码。

C++客户端代码

    success = WriteFile(
    pipe,
    guiMsg,
    PIPE_BUFFER_SIZE,
    &bytesWritten,
    NULL);

C# 服务器代码

main()
    {
        NamedPipeServerStream pipeServer =
            new NamedPipeServerStream(@"ZVMonitorPipe", PipeDirection.InOut, 1, PipeTransmissionMode.Message, PipeOptions.Asynchronous);
        StreamString ss = new StreamString(pipeServer);
        ...
        ...
        string input = ss.ReadString();
        Console.WriteLine(input);
        ...
        ...
    }
public class StreamString
    {
        private Stream ioStream;
        private UnicodeEncoding streamEncoding;
        public StreamString(Stream ioStream)
        {
            this.ioStream = ioStream;
            streamEncoding = new UnicodeEncoding();
        }
        public string ReadString()
        {
            int len = 0;
            len = ioStream.ReadByte() * 64;
            len += ioStream.ReadByte();
            byte[] inBuffer = new byte[len];
            ioStream.Read(inBuffer, 0, len);
            return streamEncoding.GetString(inBuffer);
        }
...
...
...
    }

我错过了什么?

IO 看起来功能正常。您忘记了服务器中的WaitForConnection,并且忽略了所有返回代码,例如,每个ReadByte()都可以返回 -1 而不是数据。

很可能,问题在于准备要发送的缓冲区的代码,您尚未将其包含在问题中。

        len = ioStream.ReadByte() * 64;
        len += ioStream.ReadByte();

这是发送/接收缓冲区长度的非常非正统的方式。

如果您希望在每条消息之前有 16 位长度值,请在数组中读取两个字节,调用 BitConverter.ToUInt16 将它们变成一个数字,并且不要忘记在C++端应用相同的约定。