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