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

Несколько сообщений в C++

Одно TCP-соединение может передать несколько сообщений подряд без нового connect.

Каждую порцию байтов отправляют отдельным send, ответ читают recv в буфер известного размера. Нельзя полагаться на перевод строки от peer, если его не отправляли сами. На сервере после accept удобно повторить два цикла чтение-ответ, затем закрыть принятый дескриптор и прослушивающий сокет:

#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; } for (int step = 0; step < 2; ++step) { 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("ack: ") + 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; }

Клиент выполняет симметричный цикл: два раза отправит строку и прочитает ответ. После второй пары закроет сокет; сервер к этому моменту уже отправил оба ответа:

#include <arpa/inet.h> #include <cstring> #include <cstdlib> #include <iostream> #include <netinet/in.h> #include <sys/socket.h> #include <unistd.h> int main() { int fd = socket(AF_INET, SOCK_STREAM, 0); if (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(fd); return 1; } if (connect(fd, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) == -1) { close(fd); return 1; } const char* lines[2] = {"part-0\n", "part-1\n"}; for (int step = 0; step < 2; ++step) { const char* line = lines[step]; if (send(fd, line, std::strlen(line), 0) == -1) { close(fd); return 1; } char buf[128]; ssize_t got = recv(fd, buf, sizeof(buf) - 1, 0); if (got == -1) { close(fd); return 1; } buf[got] = '\0'; std::cout << buf; } close(fd); return 0; }

Две строки "a\n" и "b\n" уходят с клиента на 127.0.0.1; сервер печатает каждую с префиксом "item: ", затем закрывает соединение.

Клиент после двух строк "n1\n" и "n2\n" читает ответы "got n1" и "got n2" и выводит их в консоль.

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