Códigos de error: errno, h_errno y WSAGetLastError

En las aplicaciones winsock, los códigos de error se recuperan mediante la función WSAGetLastError , los Windows Sockets sustituyen a la función GetLastError de Windows. Los códigos de error devueltos por Windows Sockets son similares a las constantes de código de error del socket UNIX, pero todas las constantes tienen el prefijo WSA. Por lo tanto, en las aplicaciones winsock, se devolvería el código de error WSAEWOULDBLOCK, mientras que en las aplicaciones UNIX, se devolvería el código de error EWOULDBLOCK.

Los códigos de error establecidos por Windows Sockets no están disponibles a través de la variable errno . Además, para la clase getXbyY de funciones, los códigos de error no están disponibles a través de la variable h_errno . La función WSAGetLastError está pensada para proporcionar una manera confiable de un subproceso en un proceso multiproceso para obtener información de error por subproceso.

Por compatibilidad con Berkeley UNIX (BSD), las versiones anteriores de Windows (Windows 95 con windows Socket 2 Update y Windows 98, por ejemplo) redefiniron las constantes de error normales de Berkeley normalmente encontradas en errno.h en BSD como los errores de WSA de Windows Sockets equivalentes. Por ejemplo, ECONNREFUSED se definió como WSAECONNREFUSED en el archivo de encabezado Winsock.h . En versiones posteriores de Windows (Windows NT 3.1 y versiones posteriores), estas defines se comentaron para evitar conflictos con errno.h usados con Microsoft C/C++ y Visual Studio.

El archivo de encabezado Winsock2.h incluido con el Kit de desarrollo de software (SDK) de Microsoft Windows, el Kit de desarrollo de software de plataforma (SDK) y Visual Studio todavía contiene un bloque de definición comentado dentro de un bloque #ifdef 0 y #endif que definen los códigos de error del socket BSD para que sean los mismos que las constantes de error de WSA. Se pueden usar para proporcionar cierta compatibilidad con la programación de sockets UNIX, BSD y Linux. Para la compatibilidad con BSD, una aplicación puede optar por cambiar Winsock2.h y quitar la marca de comentario de este bloque. Sin embargo, no se recomienda encarecidamente a los desarrolladores de aplicaciones quitar la marca de comentario de este bloque debido a conflictos inevitables con errno.h en la mayoría de las aplicaciones. Además, los errores de socket BSD se definen en valores muy diferentes de los que se usan en programas UNIX, BSD y Linux. Se recomienda encarecidamente a los desarrolladores de aplicaciones que usen las constantes de error de WSA en las aplicaciones de socket.

Estas define permanecen comentadas en el encabezado Winsock2.h dentro de un bloque #ifdef 0 y #endif. Si un desarrollador de aplicaciones insiste en usar los códigos de error BSD para la compatibilidad, una aplicación puede optar por incluir una línea del formulario:

#include <windows.h>

#define errno WSAGetLastError()

Esto permite que el código de red que se escribió use el errno global para funcionar correctamente en un entorno de un solo subproceso. Hay algunos inconvenientes muy graves. Si un archivo de código fuente incluye código que inspecciona errno para las funciones de socket y no socket, no se puede usar este mecanismo. Además, no es posible que una aplicación asigne un nuevo valor a errno. (En Windows Sockets, la función WSASetLastError se puede usar para este propósito).

Estilo típico de BSD

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

Estilo preferido

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

Aunque las constantes de error coherentes con Berkeley Sockets 4.3 se proporcionan con fines de compatibilidad, se recomienda encarecidamente que las aplicaciones usen las definiciones de código de error de WSA. Esto se debe a que los códigos de error devueltos por ciertas funciones de Windows Sockets se encuentran en el intervalo estándar de códigos de error tal como se define en Microsoft C©. Por lo tanto, una versión mejor del fragmento de código fuente anterior es:

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

La especificación de Winsock 1.1 original definida en 1995 recomienda un conjunto de códigos de error y enumera los posibles errores que se pueden devolver como resultado de cada función. Windows Sockets 2 agregó funciones y características con otros códigos de error de Windows Sockets devueltos además de los enumerados en la especificación winsock original. Se han agregado funciones adicionales con el tiempo para mejorar Winsock para que los desarrolladores los usen. Por ejemplo, se agregaron nuevas funciones de servicio de nombre (getaddrinfo y getnameinfo, por ejemplo) que admiten IPv6 e IPv4 en Windows XP y versiones posteriores. Algunas de las funciones de servicio de nombre IPv4 anteriores (por ejemplo, la clase getXbyY de funciones) han quedado en desuso.

En la sección códigos de error de Windows Sockets se ofrece una lista completa de los posibles códigos de error devueltos por las funciones de Windows Sockets.

Control de errores de Winsock

Migración de aplicaciones de socket a Winsock

Códigos de error de Windows Sockets

Consideraciones de programación de Winsock