Fehlercodes: errno, h _ errno und WSAGetLastError

In Winsock-Anwendungen werden Fehlercodes mithilfe der WSAGetLastError-Funktion abgerufen, die Windows Sockets ersetzen die Windows GetLastError-Funktion. Die von Windows Sockets zurückgegebenen Fehlercodes ähneln UNIX Socketfehlercodekonst constants, aber allen Konstanten wird WSA vorangestellt. In Winsock-Anwendungen würde also der WSAEWOULDBLOCK-Fehlercode zurückgegeben, während in UNIX-Anwendungen der EWVLDBLOCK-Fehlercode zurückgegeben würde.

Fehlercodes, die von Windows Sockets festgelegt werden, werden nicht über die errno-Variable verfügbar gemacht. Darüber hinaus werden fehlercodes für die getXbyY-Klasse von Funktionen nicht über die h _ errno-Variable verfügbar gemacht. Die WSAGetLastError-Funktion soll einem Thread in einem Multithreadprozess eine zuverlässige Möglichkeit bieten, Fehlerinformationen pro Thread zu erhalten.

Aus Kompatibilitäts- und BSD-Kompatibilitätsproblemen wurden in frühen Versionen von Windows (Windows 95 mit dem Windows Socket 2 Update und Windows 98) reguläre Fehlerkonst constants in der Regel in errno.h unter BSD als entsprechende Windows Sockets WSA-Fehler neu definiert. UNIX So wurde z. B. ECONNREFUSED in der Headerdatei Winsock.h als WSAECONNREFUSED definiert. In nachfolgenden Versionen von Windows (Windows NT 3.1 und höher) wurden diese Definitionen auskommentiert, um Konflikte mit "errno.h" zu vermeiden, die mit Microsoft C/C++ und Visual Studio.

Die Winsock2.h-Headerdatei, die im Microsoft Windows Software Development Kit (SDK), im Platform Software Development Kit (SDK) und im Visual Studio enthalten ist, enthält weiterhin einen auskommentierten Block von Definitionen innerhalb eines ifdef 0- und endif-Blocks, der die # BSD-Socketfehlercodes so definiert, dass sie mit den WSA-Fehlerkonst constants identisch # sind. Diese können verwendet werden, um Kompatibilität mit der UNIX, BSD und Linux-Socketprogrammierung zu gewährleisten. Aus Kompatibilitäts- und BSD-Kompatibilitätsgefässen kann eine Anwendung winsock2.h ändern und die Auskommentierung dieses Blocks auswählen. Anwendungsentwickler werden jedoch dringend davon abgeraten, diesen Block auskommentiert zu lassen, da in den meisten Anwendungen unvermeidbare Konflikte mit "errno.h" entstehen. Außerdem werden die BSD-Socketfehler in sehr unterschiedlichen Werten definiert, als sie in UNIX, BSD und Linux-Programmen verwendet werden. Anwendungsentwicklern wird dringend empfohlen, die WSA-Fehlerkonstationen in Socketanwendungen zu verwenden.

Diese Definitionen bleiben im Winsock2.h-Header innerhalb eines # ifdef 0- und # endif-Blocks auskommentiert. Wenn sich ein Anwendungsentwickler zur Verwendung der BSD-Fehlercodes aus Kompatibilitäts- und Kompatibilitätsproblemen entscheidet, kann eine Anwendung eine Zeile des Folgenden enthalten:

#include <windows.h>

#define errno WSAGetLastError()

Dadurch kann Netzwerkcode, der für die Verwendung des globalen Errno geschrieben wurde, in einer Singlethreadumgebung ordnungsgemäß funktionieren. Es gibt einige sehr schwerwiegende Nachteile. Wenn eine Quelldatei Code enthält, der errno sowohl auf Socket- als auch auf Nicht-Socketfunktionen überprüft, kann dieser Mechanismus nicht verwendet werden. Darüber hinaus ist es für eine Anwendung nicht möglich, errno einen neuen Wert zu zuweisen. (In Windows Sockets kann die Funktion WSASetLastError für diesen Zweck verwendet werden.)

Typischer BSD-Stil

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

Bevorzugter Stil

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

Obwohl Fehlerkonstationen, die mit Sockets 4.3 von Sockets 4.3 übereinstimmen, aus Kompatibilitätsgründen bereitgestellt werden, wird Anwendungen dringend empfohlen, die WSA-Fehlercodedefinitionen zu verwenden. Dies liegt daran, dass fehlercodes, die von bestimmten Windows Sockets-Funktionen zurückgegeben werden, in den Standardbereich von Fehlercodes fallen, wie von Microsoft C©. Daher ist eine bessere Version des vorangehenden Quellcodefragments:

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

Die ursprüngliche Winsock 1.1-Spezifikation aus dem Jahr 1995 hat eine Reihe von Fehlercodes empfohlen und die möglichen Fehler aufgelistet, die als Ergebnis jeder Funktion zurückgegeben werden können. Windows Sockets 2 hat Funktionen und Features mit anderen Windows Sockets-Fehlercodes hinzugefügt, die zusätzlich zu den in der ursprünglichen Winsock-Spezifikation aufgeführten zurückgegeben wurden. Im Laufe der Zeit wurden zusätzliche Funktionen hinzugefügt, um Winsock für die Verwendung durch Entwickler zu verbessern. Beispielsweise wurden neue Namensdienstfunktionen ( z. B.getaddrinfo und getnameinfo)hinzugefügt, die sowohl IPv6 als auch IPv4 auf Windows XP und höher unterstützen. Einige der älteren Nur-IPv4-Namensdienstfunktionen (z. B. die getXbyY-Klasse von Funktionen) sind veraltet.

Eine vollständige Liste der möglichen Fehlercodes, die von Windows Sockets-Funktionen zurückgegeben werden, finden Sie im Abschnitt Windows Sockets-Fehlercodes.

Behandeln von Winsock-Fehlern

Portieren von Socketanwendungen zu Winsock

Windows Socketfehlercodes

Überlegungen zur Winsock-Programmierung