Partager via


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 Windows GetLastError. Les codes d’erreur retournés par windows Sockets 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 windows Sockets ne sont pas disponibles via la variable errno. De plus, pour la classe getXbyY de fonctions, les codes d’erreur ne sont pas disponibles via la variable h_errno. La fonction WSAGetLastError est conçue pour offrir une méthode fiable permettant à un thread, dans un processus multithread, d’obtenir les informations d’erreur spécifiques à chaque 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) ont redéfini 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 Windows Sockets équivalentes. Par exemple, ECONNREFUSED a été défini comme WSAECONNREFUSED dans le fichier d’en-tête Winsock.h. Dans les versions suivantes 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ées 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, ainsi que le Kit de développement logiciel (SDK) de la plateforme et Visual Studio, contient toujours un bloc de définitions commenté, encadré par un bloc #ifdef 0 et #endif, qui attribue aux codes d’erreur de socket BSD les mêmes valeurs que les constantes d’erreur WSA. Elles peuvent être utilisées pour assurer une compatibilité avec la programmation de sockets UNIX, BSD et Linux. Pour la compatibilité avec BSD, une application peut choisir de modifier la Winsock2.h et de supprimer les marques de commentaire de ce bloc. Toutefois, il est fortement déconseillé aux développeurs d'applications d'enlever les commentaires de 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 très fortement encouragés à utiliser les constantes d’erreur WSA dans les applications de socket.

Ces définitions sont commentées dans l’en-tête Winsock2.h, entre un bloc #ifdef 0 et #endif. Si un développeur d’applications 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 d’utiliser le global errno 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 Windows Sockets, 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)
    {...}

Les styles ci-dessus nécessitent la redéfinition des constantes d'erreur de socket BSD par les constantes d'erreur WSA afin de fonctionner correctement. Bien que les constantes d’erreur cohérentes avec Berkeley Sockets 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 Windows Sockets appartiennent à la plage standard de codes d’erreur tel que défini par Microsoft C©. Ainsi, une meilleure version du fragment de code source précédent est la suivante :

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

La spécification Winsock 1.1 d’origine définie en 1995 a recommandé un ensemble de codes d’erreur et listé les erreurs possibles qui peuvent être retournées à la suite de chaque fonction. Windows Sockets 2 a ajouté des fonctions et fonctionnalités avec d’autres codes d’erreur Windows Sockets 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 noms IPv4 (la classe getXbyY de fonctions, par exemple) ont été rendues obsolètes.

Une liste complète des codes d'erreur possibles retournés par les fonctions Windows Sockets est donnée dans la section intitulée Codes d'erreur Windows Sockets.

Gestion des erreurs Winsock

portage d’applications de socket vers Winsock

Les Codes d’erreur Windows Sockets

Considérations relatives à la programmation Winsock