Создание сокета для клиента
После инициализации объект СОКЕТ должен быть инициализирован для использования клиентом.
Создание сокета
Объявите объект addrinfo, содержащий структуру sockaddr, и инициализируйте эти значения. Для этого приложения семейство адресов Интернета не указано таким образом, чтобы можно было вернуть адрес IPv6 или IPv4. Приложение запрашивает тип сокета "stream socket" для протокола TCP.
struct addrinfo *result = NULL, *ptr = NULL, hints; ZeroMemory( &hints, sizeof(hints) ); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP;
Вызовите функцию 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; }
Создайте объект SOCKET с именем ConnectSocket.
SOCKET ConnectSocket = INVALID_SOCKET;
Вызовите функцию сокета и верните её значение в переменную ConnectSocket. Для этого приложения используйте первый IP-адрес, возвращаемый вызовом getaddrinfo, который соответствовал семейству адресов, типу сокета и протоколу, указанному в параметре подсказок. В этом примере был указан сокет TCP-потока с типом сокета SOCK_STREAM и протоколом IPPROTO_TCP. Семейство адресов осталось не указано (AF_UNSPEC), поэтому возвращаемый IP-адрес может быть ip-адресом IPv6 или IPv4-адресом сервера.
Если клиентское приложение хочет подключиться только с помощью IPv6 или IPv4, то семейству адресов необходимо задать значение 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);
Проверьте на наличие ошибок, чтобы убедиться, что сокет является валидным.
if (ConnectSocket == INVALID_SOCKET) { printf("Error at socket(): %ld\n", WSAGetLastError()); freeaddrinfo(result); WSACleanup(); return 1; }
Параметры, передаваемые в функцию сокета , можно изменить для различных реализаций.
Обнаружение ошибок является ключевой частью успешного сетевого кода. Если вызов сокета завершается ошибкой, возвращается INVALID_SOCKET. Инструкция "if" в предыдущем коде используется для перехвата любых ошибок, которые могли возникнуть при создании сокета. WSAGetLastError возвращает номер ошибки, связанный с последней ошибкой.
Заметка
Более обширная проверка ошибок может потребоваться в зависимости от приложения.
Например, установка hints.ai_family на AF_UNSPEC может привести к сбою вызова соединения. Если это произойдет, вместо этого используйте определенное значение IPv4 (AF_INET) или IPv6 (AF_INET6).
WSACleanup используется для прекращения использования библиотеки DLL WS2_32.
Следующий шаг: подключение к сокету
Связанные разделы