我有两个 32 位应用程序通过 Windows 中的命名管道进行通信而没有错误。
最近由于项目要求,我不得不将其中一个 32 位应用程序转换为 64 位应用程序,现在当 64 位应用程序试图通过命名管道读取数据时,它给出错误 232。32 位应用程序写入操作成功检查返回值。
任何有 Windows 命名管道 IPC 经验的人都可以指导我可能出了什么问题吗?
我在下面附上读写操作的代码片段。
管道创建:
`CString PipeNameStart = "\\\\.\\pipe\\local\\"+node->GetPipeName();
tempHandle = CreateNamedPipe(PipeNameStart,
PIPE_ACCESS_INBOUND,
PIPE_TYPE_MESSAGE | PIPE_READMODE_BYTE | PIPE_NOWAIT,
1,
node->GetPipeSize(),
node->GetPipeSize(),
0,
NULL);
if(INVALID_HANDLE_VALUE == tempHandle)
{
return FALSE;
}
node->SetPipeHandle(tempHandle);`
写操作成功:
BOOL result;
unsigned long int amount;
CString pipename = node->GetPipeName();
result = WriteFile(node->GetPipeHandle(), //Handle to pipe
message, //buffer to write from
amountToSend, //size fo the buffer
&amount, //actual amount of bytes written
NULL); //not overlapped I/O
if(FALSE == result)
{
*error = GetLastError();
}
结果成功
读操作失败:
BOOL result;
CString pipename = node->GetPipeName();
result = ReadFile(node->GetPipeHandle(), //Handle to pipe
message, //buffer to read too
bufferSize, //size fo the buffer
amountInput, //actuall amount of bytes read
NULL); //not overlapped I/O
if(FALSE == result)
{
*error = GetLastError();
}
else
{
printf("Client Request String:%s\n", message);
}
return result;
错误是 232
我尝试在写入和读取位置打印管道名称,两者相同。 write打印返回值,成功。读取文件失败,错误 232.
ERROR_NO_DATA
是什么导致错误代码 232 在读取任何数据之前通过关闭管道出现在您的系统上。在这些情况下,一个众所周知的罪魁祸首是仅使用一个命名管道在具有不同位架构的两个应用程序之间进行通信。当正确共享句柄出现问题时,例如在处理时保持打开状态或使用后清除它,就会出现这样的问题。
以下一些方法可以解决您的问题:
使用互斥体同步访问命名管道:
Pros
:确保在任何给定时间只有一个进程可以访问命名管道,防止竞争条件。
Cons
:由于同步可能会引入性能开销。
HANDLE hMutex = CreateMutex(NULL, FALSE, _T("MyNamedPipeMutex"));
if (hMutex == NULL)
{
// Handle error
}
// Synchronize access to the named pipe
WaitForSingleObject(hMutex, INFINITE);
// Perform read or write operation on the named pipe
ReleaseMutex(hMutex);
CloseHandle(hMutex);
使用带命名管道的重叠 I/O:
Pros
:允许异步通信,可以提高性能。
Cons
:实施起来可能更复杂。
OVERLAPPED overlapped;
memset(&overlapped, 0, sizeof(OVERLAPPED));
overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
// Perform read or write operation on the named pipe with overlapped I/O
DWORD dwBytesTransferred;
if (!GetOverlappedResult(node->GetPipeHandle(), &overlapped, &dwBytesTransferred, TRUE))
{
// Handle error
}
CloseHandle(overlapped.hEvent);
确保正确处理继承:
Pros
:确保管道句柄在 32 位和 64 位应用程序之间正确共享。
Cons
:可能需要更改流程创建代码。
创建管道时检查
bInheritHandle
参数,确保句柄可以被子进程继承。此外,设置 lpStartupInfo
的 CreateProcess
以包括 STARTF_USESTDHANDLES
标志,并将 hStdInput
、hStdOutput
和 hStdError
字段设置为所需的管道句柄。