Сервер TCP на C/C++ (Windows)

У процесі розробки мережевих додатків сервери TCP (Transmission Control Protocol) є основою для встановлення надійних з'єднань між сервером та його клієнтами. У цьому блозі ми розглянемо кроки для створення базового TCP сервера на C++.

Передумови

  1. Базове розуміння програмування на C++.

  2. Знайомство з концепціями програмування на сокетах.

#define _WINSOCK_DEPRECATED_NO_WARNINGS // Коли ви включаєте заголовки Winsock і використовуєте застарілі функції, компілятор може генерувати попередження, щоб заохотити розробників використовувати новіші альтернативи. Визначення _WINSOCK_DEPRECATED_NO_WARNINGS пригнічує ці попередження  
#include   
#include   
#include   

#pragma comment(lib, "ws2_32.lib")   

int main() {  
 WSADATA wsa_data{};  
 SOCKET server_socket{};  
 SOCKET client_socket{};  
 sockaddr_in server {};  

// Ініціалізує бібліотеку Winsock для включення операцій з сокетами  
//MAKEWORD(2, 2): Запитує версію 2.2 для Winsock.  
 if (WSAStartup(MAKEWORD(2, 2), &wsa_data)!=0) {  
 std::cout << "Помилка під час ініціалізації сокета..." << std::endl;  
 }  


//Створення серверного сокета  
//AF_INET: Визначає IPv4.  
//SOCK_STREAM: Вказує на TCP сокет. Для UDP-> SOCK_DGRAM  
//IPPROTO_TCP: Використовує протокол TCP.  
//Перевірка на INVALID_SOCKET: Переконується, що сокет був успішно створений.  
server_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);  
 if (server_socket == INVALID_SOCKET) {  
 std::cout << "Помилка під час створення серверного сокета" << std::endl;  
 return 1;  
 }  

//Визначення адреси сервера та прив'язка   
//inet_addr: Перетворює рядок "127.0.0.1" (localhost) в мережеву адресу.  
//htons: Перетворює порт 8080 в мережевий порядок байтів.  
 server.sin_family = AF_INET;  
 server.sin_addr.s_addr = inet_addr("127.0.0.1");  
 server.sin_port = htons(8080);  
 int server_len = sizeof(server);  

 if (bind(server_socket, (SOCKADDR*)&server, server_len) != 0) {  
 std::cout << "Не вдалося прив'язати сокет до сервера";  
 closesocket(server_socket);  
 WSACleanup();  
 return 1;  
 }  

//Переводить сокет в режим прослуховування для прийому клієнтських з'єднань.  
//SOMAXCONN: Встановлює максимальну кількість очікуючих з'єднань  
if (listen(server_socket, SOMAXCONN) == SOCKET_ERROR) {  
 std::cerr << "Не вдалося виконати listen: " << WSAGetLastError() << std::endl;  
 closesocket(server_socket);  
 WSACleanup();  
 return 1;  
 }  

 std::cout << "Сервер працює на 127.0.0.1:8080\n";  

 int bytes = 0;  
 while (true) {  
//accept: Блокує виконання до підключення клієнта, створюючи новий сокет для клієнта.  
//Перевірка на INVALID_SOCKET: Обробка помилок підключення  
 client_socket = accept(server_socket, (SOCKADDR*) &server, &server_len);  
 if (client_socket == INVALID_SOCKET) {  
 std::cout << "Прийом з'єднання не вдався: " << WSAGetLastError() << std::endl;  
 closesocket(server_socket); //Закриття сокета   
 WSACleanup(); // WSACleanup: Очищає ресурси Winsock.  
 return 1;  
 }  

//recv: Зчитує дані, надіслані клієнтом, в буфер.  
//send: Відправляє відповідь назад клієнту.  
 char buffer[512] = {};  
 bytes = recv(client_socket, buffer, sizeof(buffer), 0);  
 if (bytes < 0) {  
 std::cout << "Не вдалося зчитати запит клієнта";  
 }  
//Повідомлення для клієнта  
 std::string body = "
Hello world
";    std::string server_message = "HTTP/1.1 200 OK\r\n"    "Content-Type: text/html\r\n"    "Content-Length: " + std::to_string(body.size()) + "\r\n\r\n" +    body;   //надсилаємо клієнту при доступі.    int byte_sent = send(client_socket, server_message.c_str(), server_message.size(), 0);    if (byte_sent < 0) {    std::cout << "Не вдалося надіслати відповідь";    }       closesocket(client_socket);    }        closesocket(server_socket);    WSACleanup();       return 0;   } ```  ## Основні моменти  1. Цей сервер є базовою реалізацією та обробляє лише один клієнт за раз.  2. Він жорстко налаштований на роботу на `127.0.0.1` (localhost) та порту `8080`.  3. Сервер відповідає фіксованим HTML повідомленням.



Перекладено з: [TCP Server in c/c++ (window)](https://medium.com/@v21it039/tcp-server-in-c-window-fdb40ecd585c)

Leave a Reply

Your email address will not be published. Required fields are marked *