Windows Sockets: Blokování
Tento článek a dva doprovodné články vysvětlují několik problémů s programováním rozhraní Windows Sockets. Tento článek se zabývá blokováním. Další problémy jsou popsané v článcích: Windows Sockets: Pořadí bajtů a Windows Sockets: Převod řetězců.
Pokud používáte nebo odvozujete z třídy CAsyncSocket, budete muset tyto problémy spravovat sami. Pokud používáte nebo odvozujete třídu CSocket, MFC je spravuje za vás.
Blokování
Soket může být v režimu blokování nebo v režimu odblokování. Funkce soketů v blokovacím (nebo synchronním) režimu se nevrací, dokud nebudou moci dokončit svou akci. To se nazývá blokování, protože soket, jehož funkce byla volána, nemůže dělat nic – je blokována – dokud volání nevrátí. Volání Receive
členské funkce může například trvat libovolně dlouhou dobu, protože čeká na odeslání aplikace (to je v případě, že používáte CSocket
, nebo používáte CAsyncSocket
s blokováním). CAsyncSocket
Pokud je objekt v neblokovacím režimu (pracuje asynchronně), volání se okamžitě vrátí a aktuální kód chyby, který je možné načíst pomocí členské funkce GetLastError, je WSAEWOULDBLOCK, což znamená, že volání by bylo zablokováno, pokud by se nevrací okamžitě z důvodu režimu. (CSocket
nikdy nevrátí WSAEWOULDBLOCK. Třída spravuje blokování za vás.)
Chování soketů se liší od 32bitových a 64bitových operačních systémů (například Windows 95 nebo Windows 98) než v 16bitových operačních systémech (například Windows 3.1). Na rozdíl od 16bitových operačních systémů používají 32bitové a 64bitové operační systémy preemptivní multitasking a poskytují multithreading. V rámci 32bitových a 64bitových operačních systémů můžete sokety umístit do samostatných pracovních vláken. Soket ve vlákně může blokovat, aniž by zasahoval do jiných aktivit v aplikaci a aniž by strávil výpočetní čas na blokování. Informace o vícevláknovém programování najdete v článku Multithreading.
Poznámka
Ve vícevláknových aplikacích můžete pomocí blokující povahy CSocket
zjednodušit návrh programu, aniž by to ovlivnilo odezvu uživatelského rozhraní. Díky zpracování uživatelských interakcí v hlavním vlákně a CSocket
zpracování v alternativních vláknech můžete tyto logické operace oddělit. V aplikaci, která není vícevláknová, musí být tyto dvě aktivity sloučeny a zpracovány jako jedno vlákno, což obvykle znamená použití CAsyncSocket
, abyste mohli zpracovávat žádosti o komunikaci na vyžádání nebo přepisovat CSocket::OnMessagePending
pro zpracování uživatelských akcí během zdlouhavé synchronní aktivity.
Zbytek této diskuze je určený pro programátory, kteří cílí na 16bitové operační systémy:
Normálně, pokud používáte CAsyncSocket
, měli byste se vyhnout použití blokujících operací a pracovat asynchronně. V asynchronních operacích od okamžiku, kdy obdržíte kód chyby WSAEWOULDBLOCK po volání Receive
, například počkáte, až bude volána členská OnReceive
funkce, aby vás upozornila, že můžete číst znovu. Asynchronní volání se provádí voláním odpovídající funkce zpětného volání soketu, jako je Například OnReceive.
V systému Windows se blokující volání považují za špatnou praxi. Ve výchozím nastavení CAsyncSocket podporuje asynchronní volání a blokování musíte spravovat sami pomocí oznámení zpětného volání. Třída CSocket, na druhé straně, je synchronní. Odčervuje zprávy Systému Windows a spravuje blokování za vás.
Další informace o blokování naleznete ve specifikaci rozhraní Windows Sockets. Další informace o funkcích On naleznete v tématu Windows Sockets: Socket Notifications a Windows Sockets: Odvození z tříd soketů.
Další informace naleznete v tématu: