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

标签 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~ 字节(在较小的 block 中,整数大小或更大)后尝试刷新,则会引发“管道损坏”异常。如果我尝试写入的字节数多于一次调用中的字节数,则 C 应用程序在读取时会崩溃。

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

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

最佳答案

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

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

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

关于c# - C# 和 C 程序之间的命名管道通信失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33570098/

相关文章:

c# - Linq to EF - 不支持的函数

c# - 使用 Automapper 将域对象转换为 ViewModel,反之亦然

c++ - 如何间接调用 C 函数

c++ - win32 应用程序不是面向对象的,为什么有这么多指针?

c# - 为什么我不能上传到ftp服务器? (仅在 IE 中,此代码适用于其他浏览器)

c# - 多线程工作线程状态

c - Libmicrohttpd和ssl

delphi - 根据正在使用的套接字杀死 Delphi 应用程序

windows - 与 Windows 服务通信的控制台应用程序

asp.net - 负载平衡的 ASP.NET Web 应用程序中的跨服务器通信