[英]Unable to read complete data from named pipe
我有一个客户端和一个服务器使用命名管道进行通信。
我正在尝试将 LPCWSTR 变量存储的地址从客户端传递到服务器。
为此,我首先将地址写入 wchar_t 缓冲区,然后向服务器发送该缓冲区的大小(作为 DWORD),因此现在服务器知道它必须读取多少字节。 我设法成功发送了缓冲区大小,但我无法发送完整的字符串。
即使服务器说它已经读取了所需的字节数,服务器端的缓冲区也没有完整的字符串。
客户:
wchar_t msgBuffer[1024];
LPCWSTR lpName = L"NameString";
_swprintf(msgBuffer, _T("%p\0"), lpName); //Write data to the buffer
DWORD nBytesToWrite = wcslen(msgBuffer); //Number of bytes to be written
bWriteFile = WriteFile( //Send the buffer size
hCreateFile,
&nBytesToWrite,
(DWORD)sizeof(nBytesToWrite),
&dwNoBytesWritten,
NULL
);
bWriteFile = WriteFile( //Send the data
hCreateFile,
msgBuffer,
(DWORD)wcslen(msgBuffer),
&dwNoBytesWritten,
NULL
);
服务器:
DWORD dwBytesToRead = 0;
bReadFile = ReadFile( //Read the size of the next message
hCreateNamedPipe,
&dwBytesToRead,
sizeof(DWORD),
&dwNoBytesRead,
NULL);
std::cout << "\nBytes to be read: " << dwBytesToRead;
wchar_t msg[] = L"";
bReadFile = ReadFile( //Read the data
hCreateNamedPipe,
&msg,
dwBytesToRead,
&dwNoBytesRead,
NULL);
std::cout << "\nBytes Read: " << dwNoBytesRead;// << '\n' << msg;
wprintf(L"\nMessage: %s\nSize: %zu", msg, wcslen(msg));
这是服务器端的输出:
要读取的字节数:9
字节读取:9
消息:78E7
尺寸:5
客户端的地址是78E7325C
,但是我的服务器只打印78E7
即使服务器说读取了 9 个字节,结果 wchar_t 的大小也只有 5,这是为什么?
编辑:我检查了客户端的缓冲区,它存储了正确的地址。 使用 WriteFile() 中的地址 (&) 运算符发送 DWORD 变量是否可以?
解决方案
将(DWORD)wcslen(nBytesToWrite)
更改为(DWORD)sizeof(nBytesToWrite)
wcslen
给出字符数,而sizeof
给出字节数,它们不一样。
C 风格的字符串表示为指向字符数组的指针,具有隐含的长度。 长度是数组中直到第一个 NUL 字符的字符数。 当您将二进制数据解释为 C 样式字符串时(您对wprintf
的调用就是这样做的),一旦找到第一个值为 0 的字符,它就会停止写入字符。
您确实能够阅读整条消息。 错误在于您验证此条件的代码基于错误的假设。 您必须在循环中输出dwNoBytesRead
字节,并且不能利用wprintf
的内置字符串功能。
除此之外,您正在读入未分配的内存。 wchar_t msg[] = L""
分配一个正好包含一个字符的数组,但您正在读入它,就好像它能够增长一样。 这不是 C 中的工作方式。您需要熟悉所使用的编程语言的基础知识。
此外,您只发送了一半的有效载荷。 WriteFile期望写入的字节数,但您传递的是wcslen的返回值,即字符数。 在 Windows 上, wchar_t
是 2 个字节宽。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.