Поделиться через


Создание сокета для клиента

После инициализации необходимо создать экземпляр объекта SOCKET для использования клиентом.

Создание сокета

  1. Объявите объект addrinfo , содержащий структуру sockaddr , и инициализируйте эти значения. Для этого приложения семейство адресов Интернета не указано, поэтому можно вернуть адрес IPv6 или IPv4. Приложение запрашивает, чтобы тип сокета был сокетом потока для протокола 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. Вызовите функцию getaddrinfo , запрашивая IP-адрес для имени сервера, переданного в командной строке. TCP-порт на сервере, к которому будет подключаться клиент, в этом примере определяется DEFAULT_PORT как 27015. Функция getaddrinfo возвращает свое значение в виде целого числа, проверяемого на наличие ошибок.

    #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. Создайте объект SOCKET с именем ConnectSocket.

    SOCKET ConnectSocket = INVALID_SOCKET;
    
  4. Вызовите функцию сокета и верните ее значение в переменную ConnectSocket. Для этого приложения используйте первый IP-адрес, возвращенный вызовом getaddrinfo , который соответствует семейству адресов, типу сокета и протоколу, указанным в параметре hints . В этом примере указан сокет потока TCP с типом сокета SOCK_STREAM и протоколом IPPROTO_TCP. Семейство адресов не указано (AF_UNSPEC), поэтому возвращенный IP-адрес может быть IPv6 или IPv4-адресом сервера.

    Если клиентское приложение хочет подключиться только по протоколу IPv6 или IPv4, в параметре hints необходимо задать для семейства адресов значение AF_INET6 для IPv6 или AF_INET для IPv4.

    // 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. Проверьте наличие ошибок, чтобы убедиться, что сокет является допустимым.

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

Параметры, передаваемые функции сокета , можно изменить для различных реализаций.

Обнаружение ошибок является ключевой частью успешного сетевого кода. Если вызов сокета завершается сбоем, он возвращает INVALID_SOCKET. Оператор if в предыдущем коде используется для перехвата ошибок, которые могли возникнуть при создании сокета. WSAGetLastError возвращает номер ошибки, связанный с последней возниквшей ошибкой.

Примечание

В зависимости от приложения может потребоваться более обширная проверка ошибок.

Например, установка hints.ai_familyAF_UNSPEC может привести к сбою вызова подключения. В этом случае используйте определенное значение IPv4 (AF_INET) или IPv6 (AF_INET6).

WSACleanup используется для прекращения использования библиотеки DLL WS2_32.

Следующий шаг. Подключение к сокету

начало работы с Winsock

Инициализация Winsock

Клиентское приложение Winsock