Kódy chyb – errno, h_errno a WSAGetLastError
V aplikacích Winsock se kódy chyb načítají pomocí funkce WSAGetLastError, windows Sockets nahradí funkci Windows GetLastError. Kódy chyb vrácené rozhraními Windows Sockets jsou podobné konstantám chybového kódu soketu UNIX, ale všechny konstanty mají předponu WSA. V aplikacích Winsock by se proto vrátil kód chyby WSAEWOULDBLOCK, zatímco v aplikacích UNIX by byl vrácen kód chyby EWOULDBLOCK.
Kódy chyb nastavené rozhraním Windows Sockets nejsou zpřístupněny prostřednictvím proměnné errno. Kromě toho pro getXbyY třídy funkcí nejsou kódy chyb zpřístupněny prostřednictvím proměnné h_errno. Funkce WSAGetLastError je určena ke spolehlivému způsobu získání informací o chybách jednotlivých vláken pro vlákno ve vícevláknovém procesu.
Z důvodu kompatibility s Berkeley UNIX (BSD) byly dřívější verze systému Windows (například Windows 95 s aktualizací Windows Socket 2 a Windows 98) redefinovány chybové konstanty Berkeley, které se běžně nacházejí v errno.h na BSD, jako ekvivalentní chyby Windows Sockets WSA. Například ECONNREFUSED byla definována jako WSAECONNREFUSED v souboru hlaviček Winsock.h. V dalších verzích Windows (Windows NT 3.1 a novějších) byly tyto definice zakomentovány, aby nedocházelo ke konfliktům s errno.h používané s Microsoft C/C++ a Visual Studio.
Soubor hlaviček Winsock2.h, který je součástí sady Microsoft Windows Software Development Kit (SDK), Platform Software Development Kit (SDK) a Visual Studio, stále obsahuje zakomentovaný blok definic uvnitř bloku #ifdef 0 a #endif, který definuje kódy chyb soketu BSD tak, aby byly shodné s chybovými konstantami WSA. Ty se dají použít k zajištění určité kompatibility s programováním soketů unixu, BSD a Linuxu. Z důvodu kompatibility s BSD se aplikace může rozhodnout změnit Winsock2.h a zrušit komentář k tomuto bloku. Vývojářům aplikací se velmi důrazně doporučuje, aby tento blok neodkomentovali kvůli nevyhnutelnému konfliktu s errno.h, který se vyskytuje ve většině aplikací. Chyby soketů BSD jsou také definovány na velmi odlišné hodnoty, než se používají v systémech UNIX, BSD a Linux. Vývojáři aplikací jsou velmi důrazně vyzýváni k používání chybových konstant WSA v soketových aplikacích.
Tyto definice zůstanou zakomentovány v hlavičce Winsock2.h v bloku #ifdef 0 a #endif. Pokud vývojář aplikace trvá na použití kódů chyb BSD pro zajištění kompatibility, může se aplikace rozhodnout, že bude obsahovat řádek formuláře:
#include <windows.h>
#define errno WSAGetLastError()
To umožňuje, aby síťový kód, který byl napsán tak, aby používal globální errno, správně fungoval v jednovláknovém prostředí. Existuje několik velmi závažných nevýhod. Pokud zdrojový soubor obsahuje kód, který kontroluje errno pro funkce jak soketové, tak nesoketové, nelze tento mechanismus použít. Kromě toho není možné, aby aplikace přiřadila novou hodnotu errno. (V rozhraní Windows Sockets lze pro tento účel použít funkci WSASetLastError.)
Typický styl BSD
r = recv(...);
if (r == -1
&& errno == EWOULDBLOCK)
{...}
Upřednostňovaný styl
r = recv(...);
if (r == -1 /* (but see below) */
&& WSAGetLastError() == EWOULDBLOCK)
{...}
Výše uvedené styly potřebují redefinici konstant chyb BSD soketů na konstanty chyb WSA, aby správně fungovaly. I když jsou pro účely kompatibility k dispozici chybové konstanty konzistentní s Berkeley Sockets 4.3, důrazně doporučujeme, aby aplikace používaly definice kódu chyby WSA. Důvodem je to, že kódy chyb vrácené určitými funkcemi Windows Sockets spadají do standardního rozsahu kódů chyb definovaných jazykem Microsoft C©. Lepší verze předchozího fragmentu zdrojového kódu je tedy:
r = recv(...);
if (r == -1 /* (but see below) */
&& WSAGetLastError() == WSAEWOULDBLOCK)
{...}
Původní specifikace Winsock 1.1 definovaná v roce 1995 doporučila sadu kódů chyb a uvádí možné chyby, které lze vrátit v důsledku každé funkce. Rozhraní Windows Sockets 2 přidalo funkce a vlastnosti, přičemž se vracejí další kódy chyb Windows Sockets, kromě těch uvedených v původní specifikaci Winsock. V průběhu času byly přidány další funkce, které vylepšují rozhraní Winsock pro použití vývojáři. Byly přidány nové funkce pojmenovací služby (getaddrinfo a getnameinfo), které podporují IPv6 i IPv4 ve Windows XP a novějších. Některé starší funkce názvové služby jen pro IPv4 (například getXbyY třídy funkcí) jsou zastaralé.
Úplný seznam možných chybových kódů vrácených funkcemi Windows Sockets je uveden v části Kódy chyb rozhraní Windows Sockets.
Související témata