Программирование сокетов на C++

Programmirovanie Soketov Na C



Программирование сокетов стало важным предметом в области компьютерных сетей. Он предполагает установление соединения между двумя узлами, сервером и клиентом для бесперебойной связи друг с другом. Сервер действует как прослушиватель канала связи и прослушивает клиента на определенном порту по IP-адресу. С другой стороны, клиент выступает в качестве коммуникатора в канале связи. Клиент связывается с сервером, чтобы создать соединение и установить контакт с сервером. Целью этой статьи является предоставление всеобъемлющего и подробного руководства по программированию сокетов на C++, охватывающего основы, представляющего практические примеры и дающего подробное объяснение кода.

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

Программирование сокетов — это процесс, который создает канал связи между сервером и клиентом с помощью сокетов. В следующем примере кода клиент устанавливает контакт с сервером, и сервер настраивается на прием клиентских подключений. Давайте разберемся с сегментами кода сервера и клиента, продемонстрировав их ядро, работающее в рамках сетевой связи. Ниже приведен серверный код. Давайте сначала посмотрим код, а затем объясним его подробно, шаг за шагом.

1. Серверная часть







Код серверной части модели приведен ниже. Давайте посмотрим, что происходит в коде:



#include
#include
#include
#include

с использованием пространство имен стандартный ;

#define ПОРТ 8080
#define MAX_BUF_SIZE 1024

интервал основной ( ) {
интервал ser_socket, cli_socket ;
структура sockaddr_in ser_address, cli_address ;
голец буф [ MAX_BUF_SIZE ] '=' { 0 } ;

если ( ( ser_socket '=' разъем ( AF_INET, SOCK_STREAM, 0 ) ) == - 1 ) {
ошибка ( «Ошибка создания сокета» ) ;
Выход ( EXIT_FAILURE ) ;
}

ser_address. sin_family '=' ОФ_ИНЕТ ;
ser_address. грех_адрес . s_addr '=' INADDR_ANY ;
ser_address. грех_порт '=' тонны ( ПОРТ ) ;

если ( связывать ( быть_сокет, ( структура sockaddr * ) & сер_адрес, размер ( ser_address ) ) == - 1 ) {
ошибка ( «Ошибка привязки» ) ;
Выход ( EXIT_FAILURE ) ;
}

если ( слушать ( быть_сокет, 3 ) == - 1 ) {
ошибка ( «Не удалось прослушать» ) ;
Выход ( EXIT_FAILURE ) ;
}

расчет << 'Сервер прослушивает порт' << ПОРТ << '... \п ' ;

socklen_t cli_address_len '=' размер ( cli_address ) ;
если ( ( cli_socket '=' принимать ( быть_сокет, ( структура sockaddr * ) & cli_адрес, & cli_address_len ) ) == - 1 ) {
ошибка ( «Не удалось принять» ) ;
Выход ( EXIT_FAILURE ) ;
}

читать ( cli_socket, буф, MAX_BUF_SIZE ) ;
расчет << «Сообщение клиента: » << буф << конец ;

отправлять ( cli_socket, «Сообщение сервера» , стрлен ( «Сообщение сервера» ) , 0 ) ;

закрывать ( cli_socket ) ;
закрывать ( ser_socket ) ;

возвращаться 0 ;
}

Данный пример представляет собой серверный код программы на C++. Этот код работает для простого TCP-сервера, который прослушивает соединения на одном конкретном порту. Когда соединение будет успешно создано, сервер получит сообщение, отправленное от клиента. После этого он печатает его на консоли и отправляет ответное сообщение клиенту. Давайте разберемся в каждой строке кода.



Программа начинается с включения библиотек: «iostream» для стандартных определений ввода/вывода, «cstring» для функций обработки строк, «unistd.h» для обеспечения доступа к API операционной системы POSIX и «arpa/inet.h» для выполнять интернет-операции. Оператор «#define PORT 8080» означает, что он определяет номер порта 8080, который будет прослушивать сервер. «#define MAX_BUF_SIZE 1024» означает максимальный размер буфера для входящих данных, который равен 1024.





В основной функции инициализируются две переменные: «ser_socket» и «cli_socket», представляющие сервер и клиент соответственно. Остальные три переменные — «sockaddr_in», «ser_address» и «cli_address» типа «struct» — инициализируются как структуры адресов для сервера и клиента. После этого инициализируется буфер с именем «buf», в котором хранятся данные, поступающие от клиента.

Функция socket() в условии «if» создает новый TCP-сокет. AF_INET обозначает IPv4, SOCK_STREAM представляет ориентированный на соединение и надежный TCP-сокет, последний аргумент, равный 0, задается для выбора протокола TCP по умолчанию, INADDR_ANY принимает соединения по любому IP-адресу, а htons (PORT) преобразует номер порта из порядок байтов хоста к порядку байтов сети.



Поскольку все определено правильно, следующим шагом будет настройка сервера в качестве листера на заданном порту и прием подключений на любом сетевом интерфейсе. Сокет передается с информацией в «ser_address» методом связывания (). Мы печатаем сообщение об ошибке и завершаем процесс, если привязка не удалась. Функция Accept() открывает новый сокет для соединения с клиентом, тогда как функция Listen() инструктирует сервер ожидать входящих соединений. Если функция Accept() завершается с ошибкой, выводится сообщение об ошибке и функция завершается.

Затем сервер считывает клиентское сообщение с помощью функции read() в буфер «buf», а затем выводит его на консоль. Функция send() используется сервером для отправки сообщения в ответ клиенту. Наконец, используя функцию close(), сервер закрывает сокет клиента, завершая работу программы, так что все соединения закрываются должным образом и исключается вероятность утечки данных.

2. Клиентская часть

Теперь давайте посмотрим, что происходит в клиентской модели:

#include
#include
#include
#include

#define ПОРТ 8080
#define SERVER_IP '127.0.0.1'

интервал основной ( ) {
интервал cli_socket ;
структура sockaddr_in ser_address ;
константа голец * сообщение '=' «Клиент передает привет!» ;

если ( ( cli_socket '=' разъем ( AF_INET, SOCK_STREAM, 0 ) ) == - 1 ) {
ошибка ( «Ошибка создания сокета» ) ;
Выход ( EXIT_FAILURE ) ;
}

ser_address. sin_family '=' ОФ_ИНЕТ ;
ser_address. грех_порт '=' тонны ( ПОРТ ) ;

если ( inet_pton ( AF_INET, SERVER_IP, & ser_address. грех_адрес ) <= 0 ) {
ошибка ( 'Неправильный адрес' ) ;
Выход ( EXIT_FAILURE ) ;
}

если ( соединять ( cli_socket, ( структура sockaddr * ) & сер_адрес, размер ( ser_address ) ) == - 1 ) {
ошибка ( «Ошибка соединения» ) ;
Выход ( EXIT_FAILURE ) ;
}
отправлять ( cli_socket, сообщение, стрлен ( сообщение ) , 0 ) ;

голец буф [ 1024 ] '=' { 0 } ;
читать ( cli_socket, буф, размер ( буф ) ) ;
стандартный :: расчет << 'Ответ сервера: ' << буф << стандартный :: конец ;

закрывать ( cli_socket ) ;
возвращаться 0 ;
}

Давайте посмотрим каждую строку кода, чтобы понять, как работает программа.

Те же четыре библиотеки — iostream, cstring, unistd.h и arpa/inet.h — также включены на стороне клиента. Номер порта также определяется вместе с IP-адресом локального хоста 127.0.0.1. Указано сообщение, которое необходимо доставить на сервер. Клиенту и серверу необходимо установить соединение следующим образом:

«if ((client_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1);» создает сокет для IPv4 с типом потока и протоколом TCP по умолчанию. Функция perror() выводит подробную информацию об ошибке, если функции socket() не удается установить соединение, и завершает программу.

«server_address.sin_port = htons(PORT);» устанавливает номер порта после преобразования в сетевой порядок байтов. После этого здесь выводится еще одно сообщение об ошибке «Неправильный адрес», которое печатается, если с адресом что-то не так. Найдя адрес в «ser_address», клиент подключится к серверу. Если соединение не установлено, распечатываются сведения об ошибке. Функция send() передаст сообщение на сервер, гарантируя, что оно не содержит никаких флагов.

Для получения и хранения ответа от сервера инициализируется буфер с именем «buf» типа «char». Функция read() считывает ответ сервера в буфер. Наконец, ответ сервера выводится на консоль. Наконец, соединение закрывается с помощью оператора close() для завершения сокета. Ниже приводится вывод программы:

Заключение

Программирование сокетов — важная часть сетевых коммуникаций в информатике. Он позволяет разрабатывать приложения, которые могут обмениваться данными по сети, предоставляя широкий спектр возможностей: от простых архитектур клиент-сервер до структурированных распределенных систем. Когда сокет создается в контексте программирования, программа должна настроить характеристики своей конечной точки, такие как протоколы TCP или UDP, а также сетевой адрес, такой как IP-адрес и номер порта. Эти сокеты позволяют серверам отправлять и получать данные. В этой статье демонстрируется практический пример того, как работает модель клиент-сервер в программировании сокетов.