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


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

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

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

  1. Функция getaddrinfo используется для определения значений в структуре sockaddr :

    • AF_INET используется для указания семейства адресов IPv4.
    • SOCK_STREAM используется для указания сокета потока.
    • IPPROTO_TCP используется для указания протокола TCP .
    • AI_PASSIVE флаг указывает, что вызывающий объект намерен использовать возвращенную структуру адреса сокета в вызове функции bind . Если флаг AI_PASSIVE установлен, а параметр nodename для функции getaddrinfo является указателем NULL , для части IP-адреса структуры адресов сокета устанавливается значение INADDR_ANY для IPv4-адресов или IN6ADDR_ANY_INIT для IPv6-адресов.
    • 27015 — это номер порта, связанный с сервером, к которому будет подключаться клиент.

    Структура addrinfo используется функцией getaddrinfo .

    #define DEFAULT_PORT "27015"
    
    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;
    hints.ai_flags = AI_PASSIVE;
    
    // Resolve the local address and port to be used by the server
    iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
    if (iResult != 0) {
        printf("getaddrinfo failed: %d\n", iResult);
        WSACleanup();
        return 1;
    }
    
  2. Создайте объект SOCKET с именем ListenSocket, чтобы сервер прослушивал клиентские подключения.

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

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

    Windows Vista и более поздних версий предоставляют возможность создания одного сокета IPv6, который помещается в режиме двойного стека для прослушивания как IPv6, так и IPv4. Дополнительные сведения об этой функции см. в разделе Сокеты с двумя стеками.

    // Create a SOCKET for the server to listen for client connections
    
    ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
    
  4. Проверьте наличие ошибок, чтобы убедиться, что сокет является допустимым.

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

Следующий шаг. Привязка сокета

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

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

Серверное приложение Winsock