Dela via


Felkoder – errno, h_errno och WSAGetLastError

I Winsock-program hämtas felkoder med hjälp av funktionen WSAGetLastError. Windows Sockets ersätter funktionen Windows GetLastError. Felkoderna som returneras av Windows Sockets liknar UNIX-socketfelkodkonstanter, men konstanterna är alla prefixade med "WSA". I Winsock-program returneras därför felkoden WSAEWOULDBLOCK, medan EWOULDBLOCK-felkoden returneras i UNIX-program.

Felkoder som anges av Windows Sockets görs inte tillgängliga via variabeln errno. För getXbyY-klass med funktioner görs felkoder dessutom inte tillgängliga via variabeln h_errno. Funktionen WSAGetLastError är avsedd att ge ett tillförlitligt sätt för en tråd i en flertrådsprocess att hämta felinformation per tråd.

För kompatibilitet med Berkeley UNIX (BSD) omdefinierade tidiga versioner av Windows (Windows 95 med Windows Socket 2 Update och Windows 98, till exempel) de vanliga Berkeley-felkonstanterna, som vanligtvis finns i errno.h på BSD, som motsvarande Windows Sockets WSA-fel. Till exempel definierades ECONNREFUSED som WSAECONNREFUSED i Winsock.h huvudfil. I efterföljande versioner av Windows (Windows NT 3.1 och senare) kommenterades dessa definitioner ut för att undvika konflikter med errno.h som används med Microsoft C/C++ och Visual Studio.

Winsock2.h--huvudfilen som ingår i Microsoft Windows Software Development Kit (SDK), Platform Software Development Kit (SDK) och Visual Studio innehåller fortfarande ett block av definitioner som har kommenterats bort med ett #ifdef 0 och #endif block. Dessa definitioner anger att BSD:s socket-felkoder ska vara samma som WSA-felkonstanterna. Dessa kan användas för att tillhandahålla viss kompatibilitet med UNIX, BSD och Linux Socket-programmering. För kompatibilitet med BSD kan ett program välja att ändra Winsock2.h och avkommentera det här blocket. Programutvecklare avråder dock starkt från att avkommentera det här blocket på grund av oundvikliga konflikter med errno.h i de flesta program. Dessutom definieras BSD-socketfelen till mycket olika värden än vad som används i UNIX-, BSD- och Linux-program. Programutvecklare uppmanas starkt att använda WSA-felkonstanterna i socketprogram.

Dessa definitioner förblir kommenterade ut i Winsock2.h-huvudfilen inom ett #ifdef 0 och #endif-block. Om en programutvecklare insisterar på att använda BSD-felkoderna för kompatibilitet kan ett program välja att inkludera en rad i formuläret:

#include <windows.h>

#define errno WSAGetLastError()

Detta gör att nätverkskod som skrevs för att använda den globala errno fungerar korrekt i en entrådad miljö. Det finns några mycket allvarliga nackdelar. Om en källfil innehåller kod som kontrollerar errno för både socket- och icke-socketfunktioner, kan den här mekanismen inte användas. Dessutom är det inte möjligt för ett program att tilldela ett nytt värde till errno. (I Windows Sockets kan funktionen WSASetLastError användas för detta ändamål.)

Typiskt BSD-format

r = recv(...);
if (r == -1
    && errno == EWOULDBLOCK)
    {...}

Önskat format

r = recv(...);
if (r == -1       /* (but see below) */
    && WSAGetLastError() == EWOULDBLOCK)
    {...}

Formatmallarna ovan behöver omdefiniera BSD-socketfelkonstanter till WSA-felkonstanter för att fungera korrekt. Även om felkonstanter som överensstämmer med Berkeley Sockets 4.3 tillhandahålls i kompatibilitetssyfte, rekommenderas program starkt att använda WSA-felkodsdefinitionerna. Det beror på att felkoder som returneras av vissa Windows Sockets-funktioner tillhör standardintervallet för felkoder som definierats av Microsoft C©. Därför är en bättre version av föregående källkodsfragment:

r = recv(...);
if (r == -1       /* (but see below) */
    && WSAGetLastError() == WSAEWOULDBLOCK)
    {...}

Den ursprungliga Winsock 1.1-specifikationen som definierades 1995 rekommenderade en uppsättning felkoder och listade möjliga fel som kan returneras som ett resultat av varje funktion. Windows Sockets 2 har lagt till funktioner och egenskaper med andra felkoder för Windows Sockets som returneras utöver de som anges i den ursprungliga Winsock-specifikationen. Ytterligare funktioner har lagts till över tid för att förbättra Winsock för användning av utvecklare. Till exempel har nya namntjänstfunktioner (getaddrinfo och getnameinfo, till exempel) lagts till som stöder både IPv6 och IPv4 i Windows XP och senare. Vissa av de äldre IPv4-namntjänstfunktionerna (till exempel getXbyY-klass med funktioner) har blivit inaktuella.

En fullständig lista över möjliga felkoder som returneras av Windows Sockets-funktioner finns i avsnittet om Felkoder för Windows Sockets.

hantering av Winsock-fel

Portera Socket-applikationer till Winsock

Felkoder för Windows Sockets

överväganden för Winsock-programmering