![](/img/trans.png)
[英]GetLastError() returns ERROR_BROKEN_PIPE after call to PeekNamedPipe only when using message mode
[英]Named pipe: ReadFile after ConnectNamedPipe return ERROR_BROKEN_PIPE
我重新激活了幾個月前我確定曾經工作過的代碼。 它讓我發瘋,但現在已經不復存在了。 我在其他問題上找不到答案。
在服務器端,我使用創建管道
#define MAX_MESSAGE_LENGTH 1024
SECURITY_ATTRIBUTES sa;
SECURITY_DESCRIPTOR sd;
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(&sd, TRUE, static_cast<PACL>(0), FALSE);
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = &sd;
sa.bInheritHandle = FALSE;
auto pipe_name = _T("\\\\.\\pipe\\") + _serviceName;
HANDLE pipe = CreateNamedPipe(
pipe_name.c_str(),
PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
1,
MAX_MESSAGE_LENGTH, MAX_MESSAGE_LENGTH, // buffer lengths (advisory)
0, // default timeout of 50ms when WaitNamedPipe uses NMPWAIT_USE_DEFAULT_WAIT
&sa));
然后一個線程等待具有ConnectNamedPipe
傳入客戶端。 ConnectNamedPipe
阻止,直到客戶端連接
HANDLE pipe = CreateFile(
pipe_name.c_str(), // pipe name
GENERIC_READ | // read and write access
GENERIC_WRITE,
0, // no sharing
NULL, // default security attributes
OPEN_EXISTING, // opens existing pipe
FILE_ATTRIBUTE_NORMAL, // default attributes
NULL); // no template file
然后,服務器上的ConnectNamedPipe
將返回TRUE
和GetLastError == 0
。 但是當它嘗試調用ReadFile
來讀取管道上的傳入數據時, ReadFile
立即返回FALSE
和GetLastError==ERROR_BROKEN_PIPE
。 在客戶端, CreateFile
返回GetLastError==231
,“所有管道實例都忙”。 雖然它是唯一的客戶! 對WaitNamedPipe(pipe, 2000)
調用返回錯誤代碼121,“信號量超時期限已過期”。 增加CreateNamedPipe
中允許的客戶端數量不會改變任何內容。
在客戶端嘗試連接的那一刻,管道似乎完全被破壞了。 但為什么? 客戶端和服務器在同一台機器上運行,具有相同的用戶甚至同一會話。 然后另一個對ConnectNamedPipe
調用因GLE = 232而失敗:“管道正在關閉”。
我還有CreateNamedPipe
其他SECURITY_ATTRIBUTES
,它允許非提升用戶連接,但這沒有區別。
此外,我嘗試在客戶端上使用CallNamedPipe
,結果相同。
PathFileExists是管道殺手! 經過幾個小時的嘗試后,我終於找到了破壞管道的東西:在管道名稱上簡單調用PathFileExists! 最近在客戶端添加了此項以檢查管道是否已創建。 我看了一下代碼更改,但我完全錯過了。 PathFileExists正確返回true或false但似乎搞亂了管道(因為我告訴它不允許多個客戶端連接)。 哎呀!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.