Creación de un socket para el cliente

Después de la inicialización, se debe crear una instancia de un objeto SOCKET para que lo use el cliente.

Para crear un socket

  1. Declare un objeto addrinfo que contenga una estructura sockaddr e inicialice estos valores. Para esta aplicación, no se especifica la familia de direcciones de Internet para que se pueda devolver una dirección IPv6 o IPv4. La aplicación solicita que el tipo de socket sea un socket de flujo para el protocolo TCP.

    struct addrinfo *result = NULL,
                    *ptr = NULL,
                    hints;
    
    ZeroMemory( &hints, sizeof(hints) );
    hints.ai_family   = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;
    
  2. Llame a la función getaddrinfo que solicita la dirección IP para el nombre del servidor pasado en la línea de comandos. El puerto TCP en el servidor al que se conectará el cliente se define mediante DEFAULT_PORT como 27015 en este ejemplo. La función getaddrinfo devuelve su valor como un entero que se comprueba si hay errores.

    #define DEFAULT_PORT "27015"
    
    // Resolve the server address and port
    iResult = getaddrinfo(argv[1], DEFAULT_PORT, &hints, &result);
    if (iResult != 0) {
        printf("getaddrinfo failed: %d\n", iResult);
        WSACleanup();
        return 1;
    }
    
  3. Cree un objeto SOCKET denominado ConnectSocket.

    SOCKET ConnectSocket = INVALID_SOCKET;
    
  4. Llame a la función socket y devuelva su valor a la variable ConnectSocket. Para esta aplicación, use la primera dirección IP devuelta por la llamada a getaddrinfo que coincida con la familia de direcciones, el tipo de socket y el protocolo especificados en el parámetro hints . En este ejemplo, se especificó un socket de flujo TCP con un tipo de socket de SOCK_STREAM y un protocolo de IPPROTO_TCP. La familia de direcciones se dejó sin especificar (AF_UNSPEC), por lo que la dirección IP devuelta podría ser una dirección IPv6 o IPv4 para el servidor.

    Si la aplicación cliente quiere conectarse con solo IPv6 o IPv4, la familia de direcciones debe establecerse en AF_INET6 para IPv6 o AF_INET para IPv4 en el parámetro hints .

    // Attempt to connect to the first address returned by
    // the call to getaddrinfo
    ptr=result;
    
    // Create a SOCKET for connecting to server
    ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, 
        ptr->ai_protocol);
    
  5. Compruebe si hay errores para asegurarse de que el socket es un socket válido.

    if (ConnectSocket == INVALID_SOCKET) {
        printf("Error at socket(): %ld\n", WSAGetLastError());
        freeaddrinfo(result);
        WSACleanup();
        return 1;
    }
    

Los parámetros pasados a la función de socket se pueden cambiar para diferentes implementaciones.

La detección de errores es una parte clave del código de red correcto. Si se produce un error en la llamada de socket , devuelve INVALID_SOCKET. La instrucción if del código anterior se usa para detectar los errores que se pueden haber producido al crear el socket. WSAGetLastError devuelve un número de error asociado al último error que se produjo.

Nota

La comprobación de errores más extensa puede ser necesaria en función de la aplicación.

Por ejemplo, establecer hints.ai_familyen AF_UNSPEC puede provocar un error en la llamada de conexión. Si esto sucede, use un valor IPv4 (AF_INET) o IPv6 (AF_INET6) específico en su lugar.

WSACleanup se usa para finalizar el uso del archivo DLL de WS2_32.

Paso siguiente: Conexión a un socket

Introducción con Winsock

Inicialización de Winsock

Aplicación cliente winsock