sockaddr_in, которую передали в прием.">
Следите за новинками
в нашем Telegram канале. Жми, чтобы подписаться:)
⊗cpSpUdRpl 684 of 696 menu
◀ ▶

Ответ по UDP в C++

Ответ по UDP не опирается на отдельный список клиентов.

После recvfrom структура отправителя лежит в sockaddr_in, которую передали в прием. Ответ собирают из короткого текста на английском и шлют тем же сокетом через sendto на этот адрес. Запрос по-прежнему приходит из фонового потока, чтобы приемник не ждал вечно.

Приемник прочитает запрос и вернет короткое подтверждение:

#include <arpa/inet.h> #include <atomic> #include <cstring> #include <netinet/in.h> #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[] = "ping"; 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) { const char reply[] = "ack"; sendto( recv_fd, reply, std::strlen(reply), 0, reinterpret_cast<sockaddr*>(&peer), peer_len ); } 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}; std::thread receiver([&]() { int recv_fd = socket(AF_INET, SOCK_DGRAM, 0); if (recv_fd == -1) { return; } 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; } ready.store(true, std::memory_order_release); 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) { const char reply[] = "got it"; sendto( recv_fd, reply, std::strlen(reply), 0, reinterpret_cast<sockaddr*>(&peer), peer_len ); } close(recv_fd); }); while (!ready.load(std::memory_order_acquire)) { } int send_fd = socket(AF_INET, SOCK_DGRAM, 0); if (send_fd == -1) { receiver.join(); return 1; } 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); receiver.join(); return 1; } const char msg[] = "hello"; if (sendto( send_fd, msg, std::strlen(msg), 0, reinterpret_cast<sockaddr*>(&dest), sizeof(dest) ) == -1) { close(send_fd); receiver.join(); return 1; } char ans_buf[256]; sockaddr_in from{}; socklen_t from_len = sizeof(from); ssize_t ans_n = recvfrom( send_fd, ans_buf, sizeof(ans_buf), 0, reinterpret_cast<sockaddr*>(&from), &from_len ); if (ans_n > 0) { std::string answer(ans_buf, static_cast<size_t>(ans_n)); std::cout << answer << "\n"; } close(send_fd); receiver.join(); return 0; }

На запрос "check" ответьте текстом "ok". Адрес отправителя возьмите из принятого пакета.

На запрос "version" ответьте "1.0" и выведите ответ на стороне отправителя в консоль.

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