V/v nebo v režimu blokování/neblokování soketu překrytý soket


Shrnutí


V tomto článku je vysvětlen rozdíl mezi překrývajícími se atributy v/v soketu a blokováním nebo režimem neblokování soketu.

Další informace


Je-li soket vytvořen, je ve výchozím nastavení blokující soket. Pomocí příkazu FIONBIO ve volání rozhraní API ioctlsocket, WSAEventSelect nebo WSAAysncSelect můžete změnit režim soketu z blokování na neblokování. Nelze-li volání rozhraní Winsock dokončit okamžitě, volání selže a funkce WSAGetLastError vrátí chybovou hodnotu WSAEWOULDBLOCK, pokud se jedná o neblokující soket, nebo o bloky volání, dokud operace neskončí, pokud se jedná o blokující soket. Překrývající se/O atribut soketu se liší od režimu blokování nebo neblokování soketu. Přestože aktuální implementace rozhraní Winsock vyžaduje překrývající se vstupně-O atribut pro režim neblokující soket, jsou koncepčně nezávislé a jejich programovací model je také odlišný. Chcete-li vytvořit soket s překrývajícími I/O atributem, můžete použít rozhraní API soketu nebo rozhraní WSASocket API s nastaveným příznakem WSA_FLAG_OVERLAPPED. Pokud překrytou vstupně-O operaci nelze dokončit okamžitě, volání selže a funkce WSAGetLastError nebo GetLastError vrátí WSA_IO_PENDING nebo ERROR_IO_PENDING, což je ve skutečnosti totéž definováno jako WSA_IO_PENDING. Další informace naleznete v následujícím článku znalostní báze Microsoft Knowledge Base:
179942 info: je třeba WSA_FLAG_OVERLAPPED pro neblokující sokety
Všimněte si, že jakmile je soket vytvořen, neexistuje způsob, jak změnit atribut překrývající soket. Můžete však volat rozhraní setsockopt API s parametrem SO_OPENTYPE u všech popisovačů soketu včetně INVALID_SOCKET pro změnu překrývajících se atributů u všech následných volání soketů ve stejném vlákně. Výchozí hodnota možnosti SO_OPENTYPE je 0, která nastavuje překrytý atribut. Všechny nenulové hodnoty možností zajistí, že soket bude synchronní a vytvoří, takže nebude možné použít funkci dokončování. Nastavením překrývajících se I/O atributů soketu se u soketu neprovádí Překrývající vstupně-O operace. Pokud například zadáte hodnotu NULL pro funkci dokončování i překrytou strukturu ve WSARecv a WSASend, nebo jednoduše zavoláte zpět nebo odešlete funkce, budou ukončeny blokováním. Chcete-li zajistit, aby byla vstupně-O činnost prováděna v překrývajících se módě, musíte v závislosti na používané funkci poskytnout překrytou strukturu ve vaší vstupně-O funkci.

Překrytý v/v

V rozhraní Winsock 1 vytvoříte překrytou soket pomocí rozhraní API soketu a pomocí souboru Win32 I/O API ReadFile, ReadFileEx, WriteFile, WriteFileEx provedete překryté v/v popisovače soketu. V rozhraní Winsock 2 vytvoříte překrytý soket pomocí WSASocket s příznakem WSA_FLAG_OVERLAPPED nebo jednoduše pomocí rozhraní API soketu. Chcete-li iniciovat překrývající se vstupně-O operaci, můžete použít výše uvedené vstupně-O API soubory Win32 nebo Winsock 2 WSASend, WSASendTo, WSARecv a Wsarecvod. Použijete-li možnost SO_RCVBUF a SO_SNDBUF k nastavení nulové vyrovnávací paměti pro příjem a odesílání zásobníku TCP, je v podstatě nutné určit, aby zásobník protokolu TCP přímo prováděl vstupně-O (vstupně/O) pomocí vyrovnávací paměti poskytované v vstupně-O volání. Z tohoto důvodu je kromě Neblokovací výhody překryté I/O (v/v) výhodou vyšší výkon, protože jste uložili kopii vyrovnávací paměti mezi vyrovnávací pamětí zásobníku protokolu TCP a uživatelskou vyrovnávací pamětí pro každý vstupně-výstup volání. Ale musíte se ujistit, že nepřistupujete k vyrovnávací paměti uživatele, jakmile je odeslána k překryté operaci a před dokončením překryté operace. Chcete-li zjistit, zda je překrývající se vstupně-O operace dokončena, můžete použít jednu z následujících možností:
  • Můžete poskytnout popisovač události v překryté struktuře použité v vstupně-O volání a počkat, až se ozve signál události.
  • Pomocí metody Getpřekrýappedresult nebo Wsagetpřekrýappedresult můžete zjišťovat stav Překrývající vstupně-O operace. V systému Windows NT můžete jako popisovač události v překryté struktuře zadat hodnotu NULL. V systému Windows 95 však překrytý struktura musí obsahovat popisovač události ručního resetování. Funkce Wsagetpřekrýappedresult v systémech Windows 98 a Windows Millennium Edition (ME) je upravena tak, že se bude chovat jako systém Windows NT a může také zjišťovat stav dokončení s popisovačem události NULL v překryté struktuře.
  • Použijte metodu ReadFileEx, WriteFileEx, WSARecv, Wsarecvz, WSASend nebo WSASendTo a zvolte, že chcete zadat funkci dokončování, která bude volána při dokončení Překrývající vstupně-výstupního operace. Pokud použijete přístup k funkci dokončování, v určitém okamžiku poté, co jste vystavila překrývající se vstupně-O operaci, je třeba vydat funkci čekání v systému Win32 nebo verzi čekací funkce WSA, která počká na nesignalizované popisovače a uvede aktuální vlákno do stavu čekání výstrahy. Po dokončení Překrývající vstupně-vstupně operace je zavolána funkce dokončení a čekací funkce se vrátí WAIT_IO_COMPLETION a váš podproces čekání na výstrahy se probudí.
  • Použijte metodu GetQueuedCompletionStatus a přidružte soket spolu s nastaveným atributem překrývajících se atributů I/O s portem pro dokončování v/v systému Windows NT (IOCP). Pomocí funkce IOCP nemusíte dodávat funkci dokončování, počkat na signál události nebo se dotazovat na stav překrývající se operace. Po vytvoření IOCP a přidání vašeho popisovače překrývajících se soketů do IOCP můžete spustit překrytou operaci pomocí kterékoli z výše uvedených vstupně-O rozhraní API (kromě recv, recvz, Send nebo SendTo). Váš pracovní podproces bude v rozhraní API GetQueuedCompletionStatus čekat na paket dokončení v/v. Po dokončení překrývajících se vstupně-dokončených paketů je přijat paket dokončování v/v a funkce GetQueuedCompletionStatus. IOCP je podpora operačního systému Windows NT, která slouží k zápisu škálovatelného serveru s vysokou propustností pomocí velmi jednoduchého podprocesu a blokovacího kódu u překrývajících se vstupně-O operací. Díky rozhraní IOCPs systému Windows NT tedy může existovat významná výkonnostní výhoda použití překrývajících se vstupně-kterých soketů.

Blokování a režim neblokování

Je-li soket vytvořen, je ve výchozím nastavení blokující soket. V rámci vstupně-vstupně-provozních operací v režimu blokování se připojují a akceptují všechny operace až do dokončení dané operace. Chcete-li změnit režim práce soketu z režimu blokování na režim bez blokování, můžete použít buď příkaz WSAAsyncSelect, WSAEventSelect, nebo příkazu FIONBIO ve volání rozhraní API ioklsocket. WSAAsyncSelect mapuje oznámení soketu na zprávy systému Windows a je nejlepším modelem pro použití GUI s jednou posloupností. Příkaz WSAEventSelect používá funkci WSAEnumNetworkEvents k určení charakteru oznámení soketu na události signalizace a k mapování upozornění soketu pomocí signalizace události. Tento model je užitečný pro aplikace bez uživatelského rozhraní, které nemají čerpadlo zpráv, jako je například aplikace služby systému Windows NT. Příkaz FIONBIO v volání rozhraní API ioctlsocket přepne soket do režimu neblokování. Je však nutné dotazovat se na stav soketu pomocí výběrového rozhraní API. Aktualizace: nastavení SO_RCVBUF na nulu s překrytím není nutné pro systém Windows 2000, který může přímo zkopírovat data do vyrovnávací paměti aplikace. Nastavení SO_SNDBUF na nulu s překrývajícími se odesláním v systému Windows 2000 má stále stejný přínos pro uložení jedné kopie paměti jako v systému Windows NT 4,0. Je také důležité, aby aplikace v případě, že aplikace nastaví odpovídající vyrovnávací paměť zásobníku na hodnotu 0, měla několik nevyřízených překrývajících se nebo recv,