Следите за новинками
в нашем Telegram канале. Жми, чтобы подписаться:)
⊗cpSpSoSrv 677 of 696 menu
◀ ▶

Сервер сокета в C++

Серверный сокет создают через socket, привязывают к порту и переводят в режим прослушивания.

Вызов accept блокирует поток, пока клиент не подключится; он возвращает отдельный дескриптор для обмена с этим клиентом. Входящие байты читают recv в буфер фиксированного размера; ответ отправляют send. Оба дескриптора закрывают перед выходом из программы.

Примем одного клиента на 127.0.0.1 и порту 18080, прочитаем строку и отправим ответ с префиксом echo: :

#include <arpa/inet.h> #include <cstring> #include <cstdlib> #include <iostream> #include <netinet/in.h> #include <sys/socket.h> #include <unistd.h> int main() { int listen_fd = socket(AF_INET, SOCK_STREAM, 0); if (listen_fd == -1) { return 1; } sockaddr_in addr{}; addr.sin_family = AF_INET; addr.sin_port = htons(18080); if (inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr) != 1) { close(listen_fd); return 1; } if (bind(listen_fd, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) == -1) { close(listen_fd); return 1; } if (listen(listen_fd, 1) == -1) { close(listen_fd); return 1; } int peer_fd = accept(listen_fd, nullptr, nullptr); if (peer_fd == -1) { close(listen_fd); return 1; } char buf[128]; ssize_t got = recv(peer_fd, buf, sizeof(buf) - 1, 0); if (got == -1) { close(peer_fd); close(listen_fd); return 1; } buf[got] = '\0'; std::string reply = std::string("echo: ") + buf; if (send(peer_fd, reply.c_str(), reply.size(), 0) == -1) { close(peer_fd); close(listen_fd); return 1; } close(peer_fd); close(listen_fd); return 0; }

Схема та же: один accept, одно чтение и один ответ. Во втором примере добавим вывод ответа на стороне клиента - для этого клиент запускают отдельно после старта сервера. Сервер вернет строку с префиксом ok: :

#include <arpa/inet.h> #include <cstring> #include <cstdlib> #include <iostream> #include <string> #include <netinet/in.h> #include <sys/socket.h> #include <unistd.h> int main() { int listen_fd = socket(AF_INET, SOCK_STREAM, 0); if (listen_fd == -1) { return 1; } sockaddr_in addr{}; addr.sin_family = AF_INET; addr.sin_port = htons(18080); if (inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr) != 1) { close(listen_fd); return 1; } if (bind(listen_fd, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) == -1) { close(listen_fd); return 1; } if (listen(listen_fd, 1) == -1) { close(listen_fd); return 1; } int peer_fd = accept(listen_fd, nullptr, nullptr); if (peer_fd == -1) { close(listen_fd); return 1; } char buf[128]; ssize_t got = recv(peer_fd, buf, sizeof(buf) - 1, 0); if (got == -1) { close(peer_fd); close(listen_fd); return 1; } buf[got] = '\0'; std::string reply = std::string("ok: ") + buf; if (send(peer_fd, reply.c_str(), reply.size(), 0) == -1) { close(peer_fd); close(listen_fd); return 1; } close(peer_fd); close(listen_fd); return 0; }

После строки "ask\n" от клиента сервер отвечает "answer: ask"; клиент выводит эту строку в консоль.

Сервер возвращает клиенту текст "pong", если получил "ping"; в консоли клиента должно быть "pong".

← →
↑
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить