windows - server ved hjælp af et overlappet navngivet rør: hvordan man bruger GetOverlappedResult () med ReadFile ()?

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg har skrevet en server og en klient, der bruger et overlappet navngivet rør. Mit problem er hovedsagelig med Readfile () og GetOverlappedResult ().


Bemærk at dette program er en testkode. Det vil blive integreret senere i en ramme (jeg 'm porting linux kode til unix, der bruger AF\_UNIX adressefamilie til socket-forbindelser)


Jeg beskriver serverdelen. Jeg har 2 tråde:


1) hovedtråden åbner et overlappende navngivet rør og slår derefter over WaitForMultipleObjects (). WaitForMultipleObjects () venter på 3 begivenheder: den 1. en venter på, at en klient tilslutter. Den anden gør det muligt for mig at afslutte programmet. Den tredje signal er signaleret, når en operation afventer i ReadFile ().


2) Den anden tråd startes, når klienten er tilsluttet. Det løkker over ReadFile ().


Her er serverkoden:


http://pastebin.com/5rka7dK7[1]


Jeg brugte hovedsagelig MSDN doc (navngivet pipeserver ved hjælp af overlappede I/O, navngivet pipe klient), SDK og andre doc på internettet for at skrive den kode. Se i [1] for klientkode. Klientkoden har brug for lidt kærlighed, men for tiden fokuserer jeg på at gøre serveren til at fungere perfekt.


Der er 4 funktioner i serverkoden (jeg glemmer den funktion, der viser fejlmeddelelser):


a) svr\_new: det skaber det overlappede navngivne rør og de 3 begivenheder og kalder ConnectNamedPipe ()


b) svr\_del frigør alle ressourcerne


c) \_read\_data\_cb: tråden der kalder ReadFile ()


d) hovedfunktionen () (hovedtråden), som løkker over WaitForMultipleObjects ()


Mit mål er at opdage i \_read\_data\_cb () når klienten afbrydes (ReadFile () fejler og GetLastError () returnerer ERROR\_BROKEN\_PIPE) og når data kommer fra klienten.


Hvad jeg ikke forstår:



  • Skal jeg ringe GetOverlappedResult ()?

  • Hvis ja, hvor? Når ReadFile () fejler og GetLastError () returnerer ERROR\_IO\_PENDING (linje 50 i pastaen)? Når WaitForMultipleObjects () returnerer (linje 303 af pastaen, kommenterede jeg koden der)? Et andet sted?

  • Jeg foretager en ResetEvent af eventet ReadFile (), når WaitForMultipleObjects () returnerer (linje 302 af pastaen). Er det det rette sted at kalde det?



Med koden jeg klistret, er her resultatet, hvis klienten sender disse 24 bytes (ReadFile () bufferen er af størrelsen 5 bytes. Jeg intentionnaly indstiller denne værdi til at teste hvad man skal gøre, hvis en klient sender nogle data større end ReadFile ( ) buffer)


meddelelse: 'salut, c' est le client! '


produktion:


$ ./server.exe
venter på klient ...
WaitForMultipleObjects: 0
klient tilsluttet (1)
WaitForMultipleObjects: 2
 * ReadFile: 5
WaitForMultipleObjects: 2
 * ReadFile: 5
WaitForMultipleObjects: 2
 * ReadFile: 5
WaitForMultipleObjects: 2
 * ReadFile: 5
WaitForMultipleObjects: 2
 * ReadFile: 4


Bemærk: WaitForMultipleObjects () kan kaldes mindre end det, det forekommer tilfældigt.


Så i min kode kalder jeg ikke getOverlappedResult (), ReadFile () lykkes (il læser 5 * 4 + 4=24 bytes), men jeg ved ikke, hvornår læsningen er færdig.


Bemærk: Jeg tilføjer en printf (), når ReadFile () mislykkes med ERROR\_IO\_PENDING, den printf () kaldes på ubestemt tid.


Desuden sender klienten 2 meddelelser. Den ene over, og en anden 3 sekunder senere. Den 2. meddelelse bliver aldrig læst, og ReadFile () mislykkes med fejlen ERROR\_SUCCESS ... (så at være præcis, returnerer ReadFile () FALSE og GetLastError () ERROR\_SUCCESS)


Så jeg er helt tabt. Jeg har søgt timer på internettet, i MSDN, i SDK-koden (Server32.c og Client32.c). Jeg ved stadig ikke, hvad jeg skal gøre i mit specifikke tilfælde.


Så, at nogen fortæller mig, hvordan man bruger GetOverlappedResult () (hvis jeg skal bruge den) for at vide, hvordan man kontrollerer om aflæsningen er færdig, og hvor? Og selv hvis nogen kan ordne min kode :-) Jeg gav koden, så alle kan teste det (jeg finder meget doc på internettet, men det er næsten altid ikke helt præcist: -/)


tak skal du have


[1] http://pastebin.com/fbCH2By8[2]

Bedste reference


Se på I/O-afslutningsporte. Efter min mening er det den mest effektive måde at modtage og håndtere anmeldelser om overlappede operationer i Windows. Så grundlæggende skal du bruge GetQueuedCompletionStatus og GetQueuedCompletionStatusEx i blokering og ikke-blokering, når du er klar til at behandle nye færdiggørelsesbegivenheder i stedet for at ringe GetOverlappedResult fra tid til anden. Faktisk kan du endda slippe af med WaitForMultipleObjects helt.


Hvilken smag af Unix er du også målrettet mod? I Solaris er der en meget lignende abstraktion. Tjek mand port\_create.


Desværre er der ikke noget lignende i Linux. Signaler (inkl. Realtid) kan til en vis grad anvendes som ventende færdiggørelsesobjekter, men de er ikke så omfattende som havne i Windows og Solaris.