我有一些管道通信代码 - 接收的字节与发送的字节不匹配。 有一个循环,调用'CallNamedPipe'向服务器发送消息。 现在只有第一条消息被完整接收,所有其余信息都被部分填充0xCD字节。 看来,当我在发送后释放内存时 - 它仍然被服务器线程读取。 MSDN说CallNamedPipe()是一个完整的消息序列:打开管道,发送字节并关闭管道。 所以,这对我来说似乎很奇怪。我必须提一下,这段代码是由VC ++ 6.0构建的 - 一个非常古老的编译器。代码在Windows 7上运行,也许我需要使用兼容模式?客户端和服务器可执行文件都在同一物理系统上运行,而不是远程运行。客户端在启动时使用CreateProcess()来启动服务器。这些消息将在稍后发送,因此竞赛条件无关紧要,我希望。
感谢您的任何建议。
============ Client side (pseudocode): ============
for (iPiece=0; iPiece < nPieces; ++iPiece)
{
buffer = malloc (2048);
// copy some data bytes into buffer (1..2048 bytes)
// log 1st 32 DWORDS from message about to be sent
if (! CallNamedPipe (name, buffer, nBytes, ..., 1000))
{
// diagnostics: call to GetLastError(), etc.
}
free (buffer);
}
============ Server side (pseudocode): ============
DWORD __stdcall ServerThreadProc (PVOID p)
{
UINT cbMaxMsg = 0x10000; // 64K for a pipe message
PVOID buffer = malloc (cbMaxMsg);
HANDLE hPipe;
BOOL fAbort = 0;
hPipe = CreateNamedPipe (name, PIPE_ACCESS_DUPLEX,
PIPE_WAIT | PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE,
PIPE_UNLIMITED_INSTANCES, cbMaxMsg, cbMaxMsg, 1000, NULL);
while (fAbort == 0) // one of pipe messages sets fAbort=1, so thread can return.
{
if (ConnectNamedPipe (hPipe, NULL))
{
DWORD bytesLoaded = 0;
ReadFile (hPipe, buffer, cbMaxMsg, &bytesLoaded, NULL);
if (bytesLoaded)
{
// log 1st 32 DWORDS from received message
// process the pipe message (switch/case)
// data may be written back to client after processing
FlushFileBuffers (hPipe);
}
DisconnectNamedPipe (hPipe);
}
else
{
// diagnostics, GLE(), etc.
}
}
free (buffer);
CloseHandle (hPipe);
return 0;
}
答案 0 :(得分:0)
使用PIPE_TYPE_MESSAGE
使管道成为消息管道。它会向服务器发出类似行为的消息。如果您尝试阅读超过标准邮件大小,它将为您提供完整的邮件。
0xCD
是标准填充,我认为它适用于堆,但不确定。
到目前为止,我们正在读取64k的数据,并写入2k的数据。看起来CallNamedPipe在数据被接受之前不会返回(因为有超时 - 设置为1000ms)。这些系统的行为是,一旦内核具有数据缓冲区,则不允许客户端代码更改内存。
我想说最可能的情况是,缓冲区未正确填充,并且服务器中的数据量与管道中的消息一致。
您没有提供足够的数据来验证这一点。