2012-10-23 79 views
0

我正在使用windows命名管道示例。當我運行示例程序來創建管道時,寫一些東西並在客戶端程序中接收它,一切都很好。當我將客戶端代碼移入在Windows服務中運行的dll時,它將不會收到發送的字節。在服務中使用的Windows命名管道不起作用

服務器的代碼如下:

ThreadParams * params = reinterpret_cast<ThreadParams*>(args); 
CString * connectionString = params->connectString; 

HANDLE hPipe; 
DWORD dwBytesRead; 
TCHAR buf[1024]; 
int len; 

hPipe = CreateNamedPipe(PIPE_NAME, // Name 
         PIPE_ACCESS_OUTBOUND | WRITE_OWNER, // OpenMode 
         PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, // PipeMode 
         2, // MaxInstances 
         1024, // OutBufferSize 
         1024, // InBuffersize 
         2000, // TimeOut 
         NULL); // Security 
if (hPipe == INVALID_HANDLE_VALUE) 
{ 
    Globals::WriteLog("Could not create the pipe",1); 
    exit(1); 
} 

Globals::WriteLog("connect...",1); 
ConnectNamedPipe(hPipe, NULL); 
Globals::WriteLog("...connected",1); 

swprintf(buf, connectionString->GetBuffer()); 
len = wcslen(buf); 

if (!WriteFile(hPipe, buf, len*sizeof(TCHAR), &dwBytesRead, NULL)) 
    Globals::WriteLog("WriteFile failed",1); 
else 
    wprintf(L"written %d bytes\n",dwBytesRead); 

DisconnectNamedPipe(hPipe); 

CloseHandle(hPipe); 

和客戶端:

CString finalResult = _T(""); 

HANDLE  hOut = INVALID_HANDLE_VALUE; 
TCHAR  buf[1024]; 
DWORD  len; 
DWORD  dwWritten; 

Global::WriteLog("pwrite: waiting for the pipe...",1); 
if (WaitNamedPipe(PIPE_NAME, NMPWAIT_WAIT_FOREVER) == 0) 
{ 
    Global::WriteLog("WaitNamedPipe failed. error=%d",1,GetLastError()); 
    goto cleanup; 
} 
Global::WriteLog("the pipe is ready",1); 

hOut = CreateFile(PIPE_NAME, 
    GENERIC_READ, 
    0, 
    NULL, OPEN_EXISTING, 
    FILE_ATTRIBUTE_NORMAL, 
    NULL); 
if (hOut == INVALID_HANDLE_VALUE) 
{ 
    Global::WriteLog("CreateFile failed with error %d",1,GetLastError()); 
    goto cleanup; 
} 
Global::WriteLog("Opened the pipe",1); 

for (;;) 
{ 
    if (!ReadFile(hOut, buf, sizeof(buf), &dwWritten, NULL)) 
    { 
     Global::WriteLog("ReadFile failed -- probably EOF. Read %d bytes.",1,dwWritten); 
     goto cleanup; 
    } 
    else 
     break; 
} 

finalResult = CString(buf); 
Global::WriteLog("String from pipe:%S",1,buf); 
cleanup: 
if(hOut != INVALID_HANDLE_VALUE) 
    CloseHandle(hOut); 

Server的代碼中,如果改變任何一個線程中運行(我用這個線程版本的示例程序進行了測試並沒有這個問題)。

爲什麼它不起作用?

在此先感謝

回答

1

好吧,似乎我明白了。看來我沒有正確理解文檔。

在服務器端,WriteFile函數在讀取字符串之前不會阻塞。我的程序只是寫數據,然後關閉句柄 - 管道。客戶端沒有收到消息,並拋出錯誤,指出管道另一端沒有進程。

也從客戶端刪除(;;)循環。

要等到讀操作在客戶端完成我加

FlushFileBuffers(hPipe); 

成功的寫操作之後。

希望幫助某人