/
bvs22
/
draft
Обзор
Документация
Войти
/
bvs22
/
draft
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
network/tcp
315 строк
10 KB
Batomunkuev Vladimir
1
01 фев 2025, 08:19
01 фев 2025, 08:19
ed6e22e
Код
Авторство
О чём код?
Конспект по TCP и использованию функций сокетов в языке C: ### Введение в TCP TCP (Transmission Control Protocol) — это протокол транспортного уровня, который обеспечивает надежную, последовательную и безошибочную передачу данных между узлами в сети. TCP гарантирует доставку данных в правильном порядке и управляет контролем потока и перегрузками. ### Основные функции для работы с TCP-сокетами в C Для работы с TCP-сокетами в C используются следующие основные функции: 1. **socket()** 2. **bind()** 3. **listen()** 4. **accept()** 5. **connect()** 6. **send()** 7. **recv()** 8. **close()** ### 1. `socket()` Функция `socket()` создает новый сокет и возвращает дескриптор сокета. ```c #include <sys/types.h> #include <sys/socket.h> // Создание сокета int socket(int domain, int type, int protocol); ``` - **Аргументы:** - `domain`: Указывает домен коммуникации (например, `AF_INET` для IPv4). - `type`: Указывает тип сокета (например, `SOCK_STREAM` для TCP). - `protocol`: Обычно ставят 0, чтобы выбрать протокол по умолчанию. - **Возвращает:** - Дескриптор сокета при успехе, -1 при ошибке. ### 2. `bind()` Функция `bind()` связывает сокет с конкретным адресом и портом. ```c #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> // Привязка сокета к адресу и порту int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); ``` - **Аргументы:** - `sockfd`: Дескриптор сокета. - `addr`: Указатель на структуру `sockaddr`, содержащую адрес и порт. - `addrlen`: Размер структуры `sockaddr`. - **Возвращает:** - 0 при успехе, -1 при ошибке. ### 3. `listen()` Функция `listen()` переводит сокет в режим прослушивания для входящих соединений. ```c #include <sys/types.h> #include <sys/socket.h> // Перевод сокета в режим прослушивания int listen(int sockfd, int backlog); ``` - **Аргументы:** - `sockfd`: Дескриптор сокета. - `backlog`: Максимальное количество ожидающих соединений. - **Возвращает:** - 0 при успехе, -1 при ошибке. ### 4. `accept()` Функция `accept()` принимает входящее соединение на сокет, находящийся в режиме прослушивания. ```c #include <sys/types.h> #include <sys/socket.h> // Принятие входящего соединения int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); ``` - **Аргументы:** - `sockfd`: Дескриптор сокета. - `addr`: Указатель на структуру `sockaddr`, в которую будет записан адрес клиента. - `addrlen`: Указатель на размер структуры `sockaddr`. - **Возвращает:** - Дескриптор нового сокета при успехе, -1 при ошибке. ### 5. `connect()` Функция `connect()` устанавливает соединение с удаленным хостом. ```c #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> // Установление соединения с удаленным хостом int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); ``` - **Аргументы:** - `sockfd`: Дескриптор сокета. - `addr`: Указатель на структуру `sockaddr`, содержащую адрес удаленного хоста. - `addrlen`: Размер структуры `sockaddr`. - **Возвращает:** - 0 при успехе, -1 при ошибке. ### 6. `send()` Функция `send()` отправляет данные через сокет. ```c #include <sys/types.h> #include <sys/socket.h> // Отправка данных через сокет ssize_t send(int sockfd, const void *buf, size_t len, int flags); ``` - **Аргументы:** - `sockfd`: Дескриптор сокета. - `buf`: Указатель на буфер с данными. - `len`: Длина данных. - `flags`: Флаги (обычно 0). - **Возвращает:** - Количество отправленных байт при успехе, -1 при ошибке. ### 7. `recv()` Функция `recv()` принимает данные через сокет. ```c #include <sys/types.h> #include <sys/socket.h> // Прием данных через сокет ssize_t recv(int sockfd, void *buf, size_t len, int flags); ``` - **Аргументы:** - `sockfd`: Дескриптор сокета. - `buf`: Указатель на буфер для хранения данных. - `len`: Размер буфера. - `flags`: Флаги (обычно 0). - **Возвращает:** - Количество принятых байт при успехе, -1 при ошибке. ### 8. `close()` Функция `close()` закрывает сокет. ```c #include <unistd.h> // Закрытие сокета int close(int sockfd); ``` - **Аргументы:** - `sockfd`: Дескриптор сокета. - **Возвращает:** - 0 при успехе, -1 при ошибке. ### Пример: Создание простого TCP-сервера ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define PORT 8080 int main() { int server_fd, new_socket; struct sockaddr_in address; int opt = 1; int addrlen = sizeof(address); char buffer[1024] = {0}; char *hello = "Hello from server"; // Создание сокета if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { perror("socket failed"); exit(EXIT_FAILURE); } // Привязка сокета к порту if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) { perror("setsockopt"); close(server_fd); exit(EXIT_FAILURE); } address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(PORT); if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { perror("bind failed"); close(server_fd); exit(EXIT_FAILURE); } // Перевод сокета в режим прослушивания if (listen(server_fd, 3) < 0) { perror("listen"); close(server_fd); exit(EXIT_FAILURE); } // Принятие входящего соединения if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) { perror("accept"); close(server_fd); exit(EXIT_FAILURE); } // Чтение данных от клиента read(new_socket, buffer, 1024); printf("Message from client: %s\n", buffer); // Отправка данных клиенту send(new_socket, hello, strlen(hello), 0); printf("Hello message sent\n"); // Закрытие сокетов close(new_socket); close(server_fd); return 0; } ``` ### Пример: Создание простого TCP-клиента ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define PORT 8080 int main() { int sock = 0; struct sockaddr_in serv_addr; char *hello = "Hello from client"; char buffer[1024] = {0}; // Создание сокета if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { printf("\n Socket creation error \n"); return -1; } serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(PORT); // Преобразование адреса IPv4 из текстового в двоичный if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) { printf("\nInvalid address/ Address not supported \n"); return -1; } // Установление соединения с сервером if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { printf("\nConnection Failed \n"); return -1; } // Отправка данных серверу send(sock, hello, strlen(hello), 0); printf("Hello message sent\n"); // Чтение данных от сервера read(sock, buffer, 1024); printf("Message from server: %s\n", buffer); // Закрытие сокета close(sock); return 0; } ``` ### Заключение Этот конспект охватывает основные функции для работы с TCP-сокетами в языке C, включая их аргументы и возвращаемые значения. Примеры простого TCP-сервера и клиента иллюстрируют, как использовать эти функции на практике.