繁体   English   中英

无法从命名管道读取完整数据

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM