Fehlercodes: errno, h_errno und WSAGetLastError

In Winsock-Anwendungen werden Fehlercodes mithilfe der WSAGetLastError-Funktion abgerufen, der Windows Sockets-Ersatz für die Windows GetLastError-Funktion . Die von Windows Sockets zurückgegebenen Fehlercodes ähneln UNIX-Socketfehlercodekonstanten, aber allen Konstanten wird WSA vorangestellt. In Winsock-Anwendungen wird daher der WSAEWOULDBLOCK-Fehlercode zurückgegeben, während in UNIX-Anwendungen der EWOULDBLOCK-Fehlercode zurückgegeben wird.

Von Windows Sockets festgelegte Fehlercodes werden nicht über die Errno-Variable verfügbar gemacht. Darüber hinaus werden fehlercodes für die getXbyY-Klasse von Funktionen nicht über die variable h_errno zur Verfügung gestellt. Die WSAGetLastError-Funktion soll eine zuverlässige Möglichkeit für einen Thread in einem Multithreadprozess zum Abrufen von Fehlerinformationen pro Thread bereitstellen.

Aus Gründen der Kompatibilität mit Berkeley UNIX (BSD) definierten frühe Versionen von Windows (z. B. Windows 95 mit Windows Socket 2 Update und Windows 98) reguläre Berkeley-Fehlerkonstanten, die normalerweise in errno.h auf BSD gefunden wurden, als die äquivalenten Windows Sockets-WSA-Fehler neu. So wurde ECONNREFUSED beispielsweise in der Winsock.h-Headerdatei 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 verwendet wird.

Die Winsock2.h-Headerdatei , die im Microsoft Windows Software Development Kit (SDK), dem Platform Software Development Kit (SDK) und Visual Studio enthalten ist, enthält weiterhin einen auskommentierte Block von Defines innerhalb eines #ifdef 0- und #endif-Blocks, die die Fehlercodes des BSD-Sockets so definieren, dass sie den WSA-Fehlerkonstanten entsprechen. Diese können verwendet werden, um eine gewisse Kompatibilität mit DER UNIX-, BSD- und Linux-Socketprogrammierung zu gewährleisten. Aus Gründen der Kompatibilität mit BSD kann eine Anwendung winsock2.h ändern und die Auskommentierung dieses Blocks aufheben. Anwendungsentwicklern wird jedoch dringend davon abgeraten, die Auskommentierung dieses Blocks aufgrund von unvermeidlichen Konflikten mit errno.h in den meisten Anwendungen aufzuheben. Außerdem werden die BSD-Socketfehler für sehr andere Werte definiert, als in UNIX-, BSD- und Linux-Programmen verwendet werden. Anwendungsentwicklern wird dringend empfohlen, die WSA-Fehlerkonstanten in Socketanwendungen zu verwenden.

Diese Definierten bleiben im Winsock2.h-Header in einem block #ifdef 0 und #endif auskommentiert. Wenn ein Anwendungsentwickler darauf besteht, die BSD-Fehlercodes aus Gründen der Kompatibilität zu verwenden, kann eine Anwendung eine Zeile des Formulars einfügen:

#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 für Socketfunktionen als auch für Nicht-Socket-Funktionen überprüft, kann dieser Mechanismus nicht verwendet werden. Außerdem ist es für eine Anwendung nicht möglich, errno einen neuen Wert zuzuweisen. (In Windows Sockets kann zu diesem Zweck die Funktion WSASetLastError verwendet werden.)

Typischer BSD-Stil

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

Bevorzugte Formatvorlage

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

Obwohl Fehlerkonstanten, die mit Berkeley Sockets 4.3 konsistent sind, aus Kompatibilitätsgründen bereitgestellt werden, wird anwendungen dringend empfohlen, die WSA-Fehlercodedefinitionen zu verwenden. Dies liegt daran, dass von bestimmten Windows Sockets-Funktionen zurückgegebene Fehlercodes in den Standardbereich von Fehlercodes fallen, wie von Microsoft C© definiert. 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, die 1995 definiert wurde, empfahl eine Reihe von Fehlercodes und listete die möglichen Fehler auf, 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 werden. 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 unter Windows XP und höher unterstützen. Einige der älteren IPv4-reinen Namensdienstfunktionen (z. B. die getXbyY-Klasse von Funktionen) sind veraltet.

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

Behandeln von Winsock-Fehlern

Portieren von Socketanwendungen zu Winsock

Windows Sockets-Fehlercodes

Überlegungen zur Winsock-Programmierung