C++: Работа с сетью и сокетами

Цель урока:
Познакомиться с сетевым программированием в C++ и научиться создавать клиент-серверные приложения.

Что мы узнаем:
  • Что такое сокеты и как их использовать.
  • Создание клиент-серверных приложений.
  • Обработка сетевых запросов.

Теоретическая часть:

Что такое сокеты?


Сокеты — это интерфейс для взаимодействия с сетью. Они позволяют создавать клиент-серверные приложения.

Пример создания сокета:
#include <sys/socket.h>
#include <netinet/in.h>

int sock = socket(AF_INET, SOCK_STREAM, 0);

Создание серверного приложения


Серверное приложение принимает соединения от клиентов и обрабатывает запросы.

Пример серверного приложения:
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>

int main() {
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(8080);
    server_addr.sin_addr.s_addr = INADDR_ANY;
    bind(sock, (sockaddr*)&server_addr, sizeof(server_addr));
    listen(sock, 5);
    int client_sock = accept(sock, NULL, NULL);
    char buffer[1024];
    recv(client_sock, buffer, sizeof(buffer), 0);
    std::cout << buffer << std::endl;
    close(client_sock);
    close(sock);
    return 0;
}

Данный фрагмент кода демонстрирует создание простого TCP-сервера на языке программирования C++. Рассмотрим пошагово каждую часть кода:

Ключевые компоненты программы:
  1. Создание сокета (socket()):
    int sock = socket(AF_INET, SOCK_STREAM, 0);

    Создается сокет типа SOCK_STREAM, работающий по протоколу IPv4 (AF_INET). Третий аргумент равен нулю, так как используем стандартные настройки протокола.
  2. Настройка адреса сервера (sockaddr_in):
    sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(8080);
    server_addr.sin_addr.s_addr = INADDR_ANY;

    Устанавливаем адрес и порт сервера. Порт задан как 8080, а IP-адрес указан как INADDR_ANY, что означает прослушивание на всех доступных интерфейсах.
  3. Связывание сокета с адресом (bind()):
    bind(sock, (sockaddr*)&server_addr, sizeof(server_addr));

    Сокет привязывается к указанному адресу и порту.
  4. Начало прослушивания соединений (listen()):
    listen(sock, 5);

    Сервер начинает прослушивать входящие соединения. Аргумент 5 указывает максимальное число соединений в очереди ожидания.
  5. Принятие входящих соединений (accept()):
    int client_sock = accept(sock, NULL, NULL);

    Принять первое соединение клиента. Возвращаемый дескриптор client_sock будет использован для взаимодействия с клиентом.
  6. Получение данных от клиента (recv()):
    char buffer[1024];
    recv(client_sock, buffer, sizeof(buffer), 0);
    std::cout << buffer << std::endl;

    Получаем данные от клиента в буфер длиной 1024 байта и выводим их на экран.
  7. Закрытие соединений (close()):
    close(client_sock);
    close(sock);

    Завершаем взаимодействие, закрывая клиентский и серверный сокеты.

Работа программы:
Программа создает сервер, слушающий на порту 8080. Когда приходит запрос от клиента, сервер принимает соединение, считывает поступившие данные и выводит их на экран. Затем обе стороны закрывают соединение.

Создание клиентского приложения


Клиентское приложение подключается к серверу и отправляет запросы.

Пример клиентского приложения:
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>

int main() {
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(8080);
    server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    connect(sock, (sockaddr*)&server_addr, sizeof(server_addr));
    send(sock, "Привет, сервер!", 14, 0);
    close(sock);
    return 0;
}

Практическая часть:
Задача 1: Создайте серверное приложение, которое принимает соединения и выводит сообщения.
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>

int main() {
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(8080);
    server_addr.sin_addr.s_addr = INADDR_ANY;

    bind(sock, (sockaddr*)&server_addr, sizeof(server_addr));
    listen(sock, 5);

    int client_sock = accept(sock, NULL, NULL);
    char buffer[1024];
    recv(client_sock, buffer, sizeof(buffer), 0);
    std::cout << buffer << std::endl;

    close(client_sock);
    close(sock);
    return 0;
}

Задача 2: Создайте клиентское приложение, которое подключается к серверу и отправляет сообщение.
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>

int main() {
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(8080);
    server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");

    connect(sock, (sockaddr*)&server_addr, sizeof(server_addr));
    send(sock, "Привет, сервер!", 14, 0);

    close(sock);
    return 0;
}

Итог урока:
Сегодня мы узнали, как создавать клиент-серверные приложения в C++. Эти знания помогут вам разрабатывать сетевые приложения.

Автор:  12 часов назад