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

时间:2015-11-06 15:26:03

标签: c# c ipc named-pipes

大家。我的团队目前正在开发一个涉及两个部分的系统: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~字节之后尝试刷新(在较小的块中,无论是整数还是更大),管道都会被打破&#39;抛出异常。如果我尝试写入多于一次调用的字节数,那么C应用程序在读取时会崩溃。

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

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

1 个答案:

答案 0 :(得分:1)

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

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

在Raymond Chen的博客上只讨论过这个问题:Changing the conditions under which ReadFile produces fewer bytes than requested,在POSIX下讨论它(严格来说,它并没有限制Win32,但确实设定了期望值Win32 API小心满足)您的假设对普通本地文件有效,但对管道无效。