Codes d’erreur : errno, h_errno et WSAGetLastError
Dans les applications Winsock, les codes d’erreur sont récupérés à l’aide de la fonction WSAGetLastError , les sockets Windows remplacent la fonction GetLastError De Windows. Les codes d’erreur retournés par les sockets Windows sont similaires aux constantes de code d’erreur de socket UNIX, mais les constantes sont toutes précédées de WSA. Par conséquent, dans les applications Winsock, le code d’erreur WSAEWOULDBLOCK est retourné, tandis que dans les applications UNIX, le code d’erreur EWOULDBLOCK est retourné.
Les codes d’erreur définis par les sockets Windows ne sont pas disponibles via la variable errno . En outre, pour la classe getXbyY des fonctions, les codes d’erreur ne sont pas disponibles via la variable h_errno . La fonction WSAGetLastError est destinée à fournir un moyen fiable pour un thread dans un processus multithread d’obtenir des informations d’erreur par thread.
Pour la compatibilité avec Berkeley UNIX (BSD), les premières versions de Windows (Windows 95 avec Windows Socket 2 Update et Windows 98, par exemple) redéfinissaient les constantes d’erreur régulières de Berkeley généralement trouvées dans errno.h sur BSD en tant qu’erreurs WSA de sockets Windows équivalentes. Par exemple, ECONNREFUSED a été défini comme WSAECONNREFUSED dans le fichier d’en-tête Winsock.h . Dans les versions ultérieures de Windows (Windows NT 3.1 et versions ultérieures), ces définitions ont été commentées pour éviter les conflits avec errno.h utilisés avec Microsoft C/C++ et Visual Studio.
Le fichier d’en-tête Winsock2.h inclus dans le Kit de développement logiciel (SDK) Microsoft Windows, le Kit de développement logiciel (SDK) de plateforme et Visual Studio contient toujours un bloc commenté de définitions dans un bloc #ifdef 0 et #endif qui définissent les codes d’erreur du socket BSD comme étant identiques aux constantes d’erreur WSA. Ils peuvent être utilisés pour assurer une certaine compatibilité avec la programmation de sockets UNIX, BSD et Linux. Pour la compatibilité avec BSD, une application peut choisir de modifier winsock2.h et de supprimer les marques de commentaire de ce bloc. Toutefois, les développeurs d’applications sont fortement déconseillés de ne pas faire de commentaire sur ce bloc en raison de conflits inévitables avec errno.h dans la plupart des applications. En outre, les erreurs de socket BSD sont définies sur des valeurs très différentes de celles utilisées dans les programmes UNIX, BSD et Linux. Les développeurs d’applications sont fortement encouragés à utiliser les constantes d’erreur WSA dans les applications de socket.
Ces définitions restent commentées dans l’en-tête Winsock2.h dans un bloc #ifdef 0 et #endif. Si un développeur d’application insiste sur l’utilisation des codes d’erreur BSD pour la compatibilité, une application peut choisir d’inclure une ligne du formulaire :
#include <windows.h>
#define errno WSAGetLastError()
Cela permet au code réseau qui a été écrit pour utiliser l’errno global de fonctionner correctement dans un environnement à thread unique. Il y a des inconvénients très sérieux. Si un fichier source inclut du code qui inspecte errno pour les fonctions socket et non socket, ce mécanisme ne peut pas être utilisé. En outre, il n’est pas possible pour une application d’affecter une nouvelle valeur à errno. (Dans les sockets Windows, la fonction WSASetLastError peut être utilisée à cet effet.)
Style BSD classique
r = recv(...);
if (r == -1
&& errno == EWOULDBLOCK)
{...}
Style préféré
r = recv(...);
if (r == -1 /* (but see below) */
&& WSAGetLastError() == EWOULDBLOCK)
{...}
Bien que des constantes d’erreur cohérentes avec les sockets Berkeley 4.3 soient fournies à des fins de compatibilité, les applications sont fortement encouragées à utiliser les définitions de code d’erreur WSA. Cela est dû au fait que les codes d’erreur retournés par certaines fonctions de sockets Windows entrent dans la plage standard de codes d’erreur telle que définie par Microsoft C©. Ainsi, une meilleure version du fragment de code source précédent est :
r = recv(...);
if (r == -1 /* (but see below) */
&& WSAGetLastError() == WSAEWOULDBLOCK)
{...}
La spécification Winsock 1.1 d’origine définie en 1995 recommandait un ensemble de codes d’erreur et listait les erreurs possibles qui peuvent être retournées à la suite de chaque fonction. Les sockets Windows 2 ont ajouté des fonctions et des fonctionnalités avec d’autres codes d’erreur de sockets Windows retournés en plus de ceux répertoriés dans la spécification Winsock d’origine. Des fonctions supplémentaires ont été ajoutées au fil du temps pour améliorer Winsock pour une utilisation par les développeurs. Par exemple, de nouvelles fonctions de service de noms (getaddrinfo et getnameinfo, par exemple) ont été ajoutées qui prennent en charge IPv6 et IPv4 sur Windows XP et versions ultérieures. Certaines des anciennes fonctions de service de nom IPv4 uniquement (la classe getXbyY de fonctions, par exemple) ont été dépréciées.
La liste complète des codes d’erreur possibles retournés par les fonctions de sockets Windows est indiquée dans la section Codes d’erreur des sockets Windows.
Rubriques connexes