2013-01-13 16 views
5

Zaczynam od nazwanych potoków i trzeba ich używać do IPC między dwoma procesami lokalnymi. Mam zarówno proces serwera, jak i klienta, używając potoku w niezablokowanym trybie nakładania.Nie blokujące zdarzenie ConnectNamedPipe nie jest sygnalizowane

Wszystko działa poprawnie (serwer pomyślnie odbiera ciąg wysyłany przez klienta), z tym że zdarzenie przekazywane do obiektu ConnectNamedPipe() przez strukturę OVERLAPPED nie jest sygnalizowane zgodnie z oczekiwaniami (sygnalizowane, gdy klient łączy się).

Podczas gdy serwer jest zablokowany w wywołaniu WaitForSingleObject(), proces klienta podłączony do potoku, wysłał swoje dane i został zakończony, ale zdarzenie nie zostało zasygnalizowane. czego mi brakuje?

kod serwera:

HANDLE hPipe = ::CreateNamedPipeW(
    L"\\\\.\\pipe\\ThePipe", 
    PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 
    PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_NOWAIT, 
    1, 
    4096, 
    4096, 
    100, 
    nullptr); 

OVERLAPPED ov = {0}; 
ov.hEvent = ::CreateEventW(nullptr, TRUE, FALSE, nullptr); 

BOOL retVal = ::ConnectNamedPipe(hPipe, &ov); 

if (retVal == 0) 
{ 
    DWORD err = ::GetLastError(); 
    if (err == ERROR_IO_PENDING) 
    { 
     ::WaitForSingleObject(ov.hEvent, 30000); 
    } 
    if (err == ERROR_PIPE_LISTENING) 
    { 
     ::WaitForSingleObject(ov.hEvent, 30000); // this blocks until time-out??? 
    } 
} 
+0

Czy odbiera ERROR_IO_PENDING? (lepiej uczynić tę sprawę łatwą do rozróżnienia lub musisz dołączyć do procesu i zobaczyć, gdzie czeka) –

Odpowiedz

10

Nie należy stosować (przestarzałe) PIPE_NOWAIT razem z trybu nakładania. PIPE_NOWAIT powoduje, że ConnectNamedPipe natychmiast zwraca ERROR_PIPE_LISTENING, jeśli klient nie jest podłączony; nakładające się we/wy po prostu się nie dzieje, a oczekiwanie na wydarzenie jest bezużyteczne.

Ustawiasz PIPE_NOWAIT i odpytujesz potok okresowo do momentu osiągnięcia sukcesu lub ustawiasz FILE_FLAG_OVERLAPPED i używasz zdarzenia do sprawdzenia/oczekiwania na zakończenie.

+1

Naprawiono problem. Dziękuję bardzo! Microsoft powinien naprawdę zaktualizować dokumentację na ten temat. – links77

+0

Ze strony MSDN na CreateNamedPipe: "Należy zauważyć, że tryb odblokowania jest obsługiwany w celu zapewnienia zgodności z programem Microsoft LAN Manager w wersji 2.0 i nie powinien być używany do uzyskania asynchronicznych operacji we/wy z nazwanymi potokami." –

+0

Istnieją ostrzeżenia dotyczące nieużywania ConnectNamedPipe w trybie asynchronicznym. Zamiast tego można przekazać strukturę 'OVERLAPPED' do' ReadFile', aby poczekać na odczyt. – Steve

Powiązane problemy