2015-11-06 140 views
1

每个人。我的团队目前正在开发一个涉及两部分的系统:C#中的数据组织,用户界面等,以及由于性能要求而在C中进行大量数据处理。我们试图压缩每一点性能,尽管最初我们正在使用文件传递这两个进程,但我们仍然通过通过IPC传递这两个进程来继续。具体命名管道。该传输所需的数据C程序的C#程序的简化版本是这样的:命名管道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程序。

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

+0

我敢肯定,这不是你如何正确序列化数据。另外,你是如何在C程序中分配'integer_array []'的? – EOF

+0

我只是发送整数。哪一种方法才是正确的做法?我曾尝试使用C中的读取方法使用单个整数作为接收缓冲区,char数组缓冲区分配为: char * buf; buf =(char *)malloc(expected_size * sizeof(int)); 或简单地作为: char buf [someSize]; –

+0

如果你正在读整数,为什么不读'(fd,...,sizeof(int)'? – EOF

回答

1

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

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

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

+0

有趣。我马上检查一下。谢谢! –

+0

我明确地忽略了读取的字节结果并添加了一个部分读取循环来等待其他数据。但是,尽管如此,在一些传输的字节数之后,这些文字仍会停止。 C程序中的读取函数不断地接收0字节,并且c#程序在刷新时崩溃,或者在调用'waitForDrain'时挂起。 我必须假设这种IPC不可能用于mingw32_64 C和C#应用程序吗? –

相关问题