Dela via


Överlappande indata/utdata

Windows Sockets 2 introducerar överlappande I/O och kräver att alla transportleverantörer stöder den här funktionen. Överlappande I/O kan endast utföras på socketar som har skapats via funktionen WSPSocket med WSA_FLAG_OVERLAPPED-flagguppsättningen och följa modellen som upprättats i Windows.

För att ta emot använder en klient WSPRecv- eller WSPRecvFrom för att tillhandahålla buffertar till vilka data ska tas emot. Om en eller flera buffertar publiceras före den tidpunkt då data har tagits emot av nätverket, är det möjligt att data placeras i användarens buffertar omedelbart när de anländer och därmed undvika kopieringsåtgärden som annars skulle inträffa. Om data tas emot när buffertar redan har publicerats kopieras de omedelbart till användarens buffertar. Om data tas emot när inga mottagningsbuffertar har postats av programmet, tillgriper tjänstleverantören den synkrona driftsstil där inkommande data buffras internt tills klienten utfärdar ett mottagningsanrop och tillhandahåller därmed en buffert som data kan kopieras till. Ett undantag till detta skulle vara om programmet som används WSPSetSockOpt för att ange storleken på mottagningsbufferten till noll. I det här fallet skulle tillförlitliga protokoll endast tillåta att data tas emot när programbuffertar har publicerats och data om otillförlitliga protokoll skulle gå förlorade.

På sändningssidan använder klienter WSPSend- eller WSPSendTo för att ange pekare till fyllda buffertar och samtycker sedan till att inte störa buffertarna på något sätt förrän nätverket har förbrukat buffertens innehåll.

Överlappade skicka och ta emot samtal returnerar omedelbart. Ett returvärde på noll anger att I/O-åtgärden slutfördes omedelbart och att motsvarande slutförandeindikator redan har inträffat. Det vill: det associerade händelseobjektet har signalerats eller så har slutföranderutinen placerats i kö via WPUQueueApc. Ett returvärde på SOCKET_ERROR tillsammans med en felkod för WSA_IO_PENDING anger att den överlappande åtgärden har initierats och att en efterföljande indikation anges när sändningsbuffertar har förbrukats eller när mottagningsbuffertar fylls. All annan felkod anger att den överlappande åtgärden inte initierades och att ingen slutförandeindikering kommer.

Både skicka och ta emot åtgärder kan överlappas. Mottagningsfunktionerna kan anropas flera gånger för att publicera mottagningsbuffertar som förberedelse för inkommande data, och sändningsfunktionerna kan anropas flera gånger för att köa flera buffertar som ska skickas. Observera att även om en serie överlappade sändningsbuffertar skickas i den angivna ordern, kan motsvarande slutförandeanteckningar inträffa i en annan ordning. På samma sätt fylls buffertar på mottagarsidan i den ordning de tillhandahålls, men kompletteringsanvisningarna kan förekomma i en annan ordning.

Funktionen för uppskjuten slutförande av överlappande I/O är också tillgänglig för WSPIoctl.

Leverans av kompletteringsanvisningarna

Tjänstleverantörer har två sätt att ange överlappande slutförande: ange ett klient angivet händelseobjekt eller anropa en klient angiven slutföranderutin. I båda fallen är en datastruktur, WSAOVERLAPPED, associerad med varje överlappande åtgärd. Den här strukturen allokeras av klienten och används av den för att ange vilket händelseobjekt (om det finns något) som ska anges när slutförandet sker. Den WSAOVERLAPPED- struktur kan användas av tjänstleverantören som en plats för att lagra en referens till resultatet (till exempel antal byte som överförs, uppdaterade flaggor, felkoder osv.) för en viss överlappande åtgärd. För att få dessa resultat måste klienterna anropa WSPGetOverlappedResultoch skicka in en pekare till motsvarande överlappande struktur.

Om händelsebaserad slutförandeindikering har valts för en viss överlappande I/O-begäran kan WSPGetOverlappedResult rutin användas av klienterna för att antingen avsöka eller vänta på att den överlappade åtgärden har slutförts. Om kompletteringsbaserad slutförandeindikering väljs för en viss överlappande I/O-begäran är endast avsökningsalternativet WSPGetOverlappedResult tillgängligt. En klient kan också använda andra sätt att vänta (till exempel att använda WSAWaitForMultipleEvents) tills motsvarande händelseobjekt har signalerats eller den angivna slutföranderutinen har anropats av tjänstleverantören. När slutförandet har angetts kan klienten anropa WSPGetOverlappedResult, med förväntningen att anropet kommer att slutföras omedelbart.

Anropa socket-I/O-slutföranderutiner

Om parametern lpCompletionRoutine till en överlappande åtgärd inte NULL-är det tjänsteleverantörens ansvar att ordna anrop av den klientdefinierade slutföranderutinen när den överlappande åtgärden slutförs. Eftersom slutföranderutinen måste köras i kontexten för samma tråd som initierade den överlappande åtgärden kan den inte anropas direkt från tjänstleverantören. Ws2_32.DLL erbjuder en APC-mekanism (asynkront proceduranrop) för att underlätta anrop av slutföranderutiner.

En tjänstleverantör ser till att en funktion körs i rätt tråd genom att anropa WPUQueueApc. Den här funktionen kan anropas från valfri process- och trådkontext, även en kontext som skiljer sig från tråden och processen som användes för att initiera den överlappande åtgärden.

WPUQueueApc- tar som indataparametrar en pekare till en WSATHREADID- struktur, en pekare till en APC-funktion som ska anropas och ett 32-bitars kontextvärde som därefter skickas till APC-funktionen. Tjänstleverantörer levereras alltid med en pekare till rätt WSATHREADID struktur via parametern lpThreadId till funktionen överlappad. Providern bör lagra WSATHREADID- struktur lokalt och ange en pekare till den här kopian av WSATHREADID struktur som en indataparameter för att WPUQueueApc. När funktionen WPUQueueApc returneras kan providern ta bort sin kopia av WSATHREADID-.

Proceduren WPUQueueApc helt enkelt innehåller tillräckligt med information för att anropa den angivna APC-funktionen med de angivna parametrarna, men anropar den inte. När måltråden anger ett aviseringsbart väntetillstånd tas den här informationen bort och ett anrop görs till APC-funktionen i måltråden och processkontexten. Eftersom APC-mekanismen endast stöder ett enda 32-bitars kontextvärde kan inte APC-funktionen själv vara den klientdefinierade slutföranderutinen, vilket omfattar fler parametrar. Tjänstleverantören måste i stället ange en pekare till sin egen APC-funktion som använder det angivna kontextvärdet för att få åtkomst till nödvändig resultatinformation för den överlappande åtgärden och sedan anropar den klientdefinierade slutföranderutinen.

För tjänstleverantörer där en komponent i användarläge implementerar överlappande I/O är en typisk användning av APC-mekanismen följande:

  • När I/O-åtgärden har slutförts allokerar providern en liten buffert och packar den med en pekare till slutförandeproceduren för klienten och parametervärden som ska skickas till proceduren.
  • Den köar en APC och anger pekaren till bufferten som kontextvärde och en egen mellanliggande procedur som målprocedur.
  • När måltråden slutligen går in i aviseringsbart väntetillstånd anropas tjänstleverantörens mellanliggande procedur i rätt trådkontext.
  • Den mellanliggande proceduren packar helt enkelt upp parametrar, frigör bufferten och anropar slutförandeproceduren som tillhandahålls av klienten.
  • För tjänstleverantörer där en komponent i kernelläge implementerar överlappande I/O är en typisk implementering liknande, förutom att implementeringen skulle använda standard kernelgränssnitt för att ange APC.

Beskrivningen av relevanta kernelgränssnitt ligger utanför omfånget för Windows Sockets 2-specifikationen.

Not

Tjänsteleverantörer måste tillåta Att Windows Sockets 2-klienter anropar sändnings- och mottagningsåtgärder inom ramen för socket-I/O-slutföranderutinen och garantera att I/O-slutföranderutiner inte kapslas för en viss socket.

 

Under vissa omständigheter kan en tjänsteleverantör i flera lager behöva initiera och slutföra överlappande åtgärder inifrån en intern arbetstråd. I det här fallet skulle en WSATHREADID- inte vara tillgänglig från ett inkommande funktionsanrop. Tjänstleverantörsgränssnittet tillhandahåller ett upprop, WPUOpenCurrentThread, för att hämta en WSATHREADID- för den aktuella tråden. När den här WSATHREADID- inte längre behövs, bör dess resurser returneras genom att anropa WPUCloseThread.