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

Прием UDP-пакета в C++

Приемник UDP держит буфер фиксированного размера и ждет первый пакет.

Вызов recvfrom заполняет буфер и возвращает число прочитанных байтов. Строку собирают только по этой длине, а не по всему массиву. Чтобы ожидание не длилось бесконечно без данных, отправку запускают в отдельном std::thread после успешного bind.

Приемник на 18081 выведет текст, а поток отправит короткое сообщение на 127.0.0.1:

#include <arpa/inet.h> #include <atomic> #include <cstring> #include <iostream> #include <netinet/in.h> #include <string> #include <sys/socket.h> #include <thread> #include <unistd.h> int main() { std::atomic<bool> ready{false}; int recv_fd = socket(AF_INET, SOCK_DGRAM, 0); if (recv_fd == -1) { return 1; } sockaddr_in local{}; local.sin_family = AF_INET; local.sin_port = htons(18081); if (inet_pton(AF_INET, "127.0.0.1", &local.sin_addr) != 1 || bind( recv_fd, reinterpret_cast<sockaddr*>(&local), sizeof(local) ) == -1) { close(recv_fd); return 1; } ready.store(true, std::memory_order_release); std::thread sender([&]() { while (!ready.load(std::memory_order_acquire)) { } int send_fd = socket(AF_INET, SOCK_DGRAM, 0); if (send_fd == -1) { return; } sockaddr_in dest{}; dest.sin_family = AF_INET; dest.sin_port = htons(18081); if (inet_pton(AF_INET, "127.0.0.1", &dest.sin_addr) != 1) { close(send_fd); return; } const char msg[] = "note"; sendto( send_fd, msg, std::strlen(msg), 0, reinterpret_cast<sockaddr*>(&dest), sizeof(dest) ); close(send_fd); }); char buf[256]; sockaddr_in peer{}; socklen_t peer_len = sizeof(peer); ssize_t n = recvfrom( recv_fd, buf, sizeof(buf), 0, reinterpret_cast<sockaddr*>(&peer), &peer_len ); if (n > 0) { std::string text(buf, static_cast<size_t>(n)); std::cout << text << "\n"; } close(recv_fd); sender.join(); return 0; }

Размер буфера задают с запасом: лишние байты в строку не попадут, если опираться на длину приема. Тот же каркас подходит для более длинного текста, когда он помещается в буфер:

#include <arpa/inet.h> #include <atomic> #include <cstring> #include <iostream> #include <netinet/in.h> #include <string> #include <sys/socket.h> #include <thread> #include <unistd.h> int main() { std::atomic<bool> ready{false}; int recv_fd = socket(AF_INET, SOCK_DGRAM, 0); if (recv_fd == -1) { return 1; } sockaddr_in local{}; local.sin_family = AF_INET; local.sin_port = htons(18081); if (inet_pton(AF_INET, "127.0.0.1", &local.sin_addr) != 1 || bind( recv_fd, reinterpret_cast<sockaddr*>(&local), sizeof(local) ) == -1) { close(recv_fd); return 1; } ready.store(true, std::memory_order_release); std::thread sender([&]() { while (!ready.load(std::memory_order_acquire)) { } int send_fd = socket(AF_INET, SOCK_DGRAM, 0); if (send_fd == -1) { return; } sockaddr_in dest{}; dest.sin_family = AF_INET; dest.sin_port = htons(18081); if (inet_pton(AF_INET, "127.0.0.1", &dest.sin_addr) != 1) { close(send_fd); return; } const char msg[] = "status ok"; sendto( send_fd, msg, std::strlen(msg), 0, reinterpret_cast<sockaddr*>(&dest), sizeof(dest) ); close(send_fd); }); char buf[512]; sockaddr_in peer{}; socklen_t peer_len = sizeof(peer); ssize_t n = recvfrom( recv_fd, buf, sizeof(buf), 0, reinterpret_cast<sockaddr*>(&peer), &peer_len ); if (n > 0) { std::string text(buf, static_cast<size_t>(n)); std::cout << text.size() << "\n"; } close(recv_fd); sender.join(); return 0; }

Примите один пакет с текстом "ready" и выведите его в консоль одной строкой.

После приема текста "metric" выведите число символов в полученной строке.

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