c#和c程序之间的命名管道通信失败

本文关键字:管道 通信 失败 程序 之间 | 更新日期: 2023-09-27 18:20:48

每个人。我的团队目前正在开发一个包含两部分的系统:C#中的数据组织、UI等,以及由于性能要求而在C中进行的繁重的数字运算。我们正在努力压缩每一点性能,因此,当最初我们使用文件来通信两个进程时,我们将通过IPC来通信这两个进程。专门命名的管道。传输C程序所需数据的C#程序的简化版本是:

String pipeName = "some_random_name";
NamedPipeServerStream pipeServer = new NamedPipeServerStream(pipeName, PipeDirection.Out, 2, PipeTransmissionMode.Byte, PipeOptions.None, 0, 4096);
Process someProcess= new Process();
someProcess.StartInfo.FileName = appDirectory + "someProcess.exe";
someProcess.StartInfo.RedirectStandardInput = true;
someProcess.StartInfo.RedirectStandardOutput = true;
someProcess.StartInfo.RedirectStandardError = false;
someProcess.StartInfo.UseShellExecute = false;
someProcess.StartInfo.Arguments = "''''.''pipe''" + pipeName;
someProcess.Start();
someProcess.PriorityClass = ProcessPriorityClass.RealTime;
pipeServer.WaitForConnection();
pipeServer.Write(BitConverter.GetBytes(lengthOfNextDataSent), 0, 4);
pipeServer.WaitForPipeDrain();
for (i = 0; i < lengthOfNextDataSent; i++){
    byte[] xBytes = BitConverter.GetBytes(SomeOtherIntegerData);
    pipeServer.Write(xBytes , 0, xBytes.Length);
}

而简化的客户端C代码是:

fd = open(argv[1], O_RDONLY);
read(fd, &received_length, sizeof(int));
for(i = 0; i < received_length; i++){
    read(fd, integer_array[i], 16);
}
close(fd);

奇怪的是,我能够正确接收(在C应用程序中)并解码多达1820个字节。如果我试图调用C#方法WaitForPipeDrain,或者在写入1820个字节(在较小的块中,整数大小或更大)后尝试刷新,则会引发"管道断开"异常。如果我试图在一次调用中写入更多的字节,C应用程序在读取时会崩溃。

编辑:我忘了提一个细节。我正在使用mingw32-64编译器在类似cygwin的环境(特别是msys2)中编译C程序。

你能告诉我我做错了什么吗?

c#和c程序之间的命名管道通信失败

您忽略了read调用的返回值,并假设整个缓冲区是有效的。

在管道上,不能忽略这一点。

Raymond Chen的博客上刚刚讨论过这一点:改变ReadFile产生比请求更少字节的条件,其中讨论了在POSIX(严格来说,它不限制Win32,但设置了Win32 API小心满足的期望)下,您的假设对普通本地文件有效,但对管道无效。