Network System 0.1.1
High-performance modular networking library for scalable client-server applications
Loading...
Searching...
No Matches
udp_echo.cpp
Go to the documentation of this file.
1/*****************************************************************************
2BSD 3-Clause License
3
4Copyright (c) 2024, Network System Project
5All rights reserved.
6*****************************************************************************/
7
33
34#include <atomic>
35#include <chrono>
36#include <iostream>
37#include <mutex>
38#include <string>
39#include <thread>
40#include <unordered_map>
41#include <vector>
42
43using namespace kcenon::network;
44
45static std::atomic<bool> g_done{false};
46
47void run_server() {
49 constexpr uint16_t port = 9003;
50
51 auto server = udp.create_server({
52 .port = port,
53 .server_id = "UdpEchoServer",
54 });
55
56 std::mutex sessions_mutex;
57 std::unordered_map<std::string, std::shared_ptr<interfaces::i_session>> sessions;
58
59 server->set_connection_callback(
60 [&sessions, &sessions_mutex](std::shared_ptr<interfaces::i_session> session) {
61 std::lock_guard<std::mutex> lock(sessions_mutex);
62 sessions[std::string(session->id())] = session;
63 std::cout << "[Server] New peer: " << session->id() << std::endl;
64 });
65
66 server->set_disconnection_callback(
67 [&sessions, &sessions_mutex](std::string_view session_id) {
68 std::lock_guard<std::mutex> lock(sessions_mutex);
69 sessions.erase(std::string(session_id));
70 });
71
72 server->set_receive_callback(
73 [&sessions, &sessions_mutex](std::string_view session_id,
74 const std::vector<uint8_t>& data) {
75 std::string msg(data.begin(), data.end());
76 std::cout << "[Server] From " << session_id << ": " << msg << std::endl;
77
78 // Echo back
79 std::shared_ptr<interfaces::i_session> session;
80 {
81 std::lock_guard<std::mutex> lock(sessions_mutex);
82 auto it = sessions.find(std::string(session_id));
83 if (it != sessions.end()) {
84 session = it->second;
85 }
86 }
87 if (session) {
88 std::string echo = "Echo: " + msg;
89 std::vector<uint8_t> echo_data(echo.begin(), echo.end());
90 session->send(std::move(echo_data));
91 }
92 });
93
94 server->set_error_callback(
95 [](std::string_view session_id, std::error_code ec) {
96 std::cerr << "[Server] Error on " << session_id << ": " << ec.message()
97 << std::endl;
98 });
99
100 std::cout << "[Server] UDP echo server on port " << port << std::endl;
101
102 while (!g_done.load()) {
103 std::this_thread::sleep_for(std::chrono::milliseconds(100));
104 }
105
106 std::cout << "[Server] Stopped." << std::endl;
107}
108
110 // Give server time to start
111 std::this_thread::sleep_for(std::chrono::milliseconds(300));
112
114 auto client = udp.create_client({
115 .host = "127.0.0.1",
116 .port = 9003,
117 .client_id = "UdpClient",
118 });
119
120 client->set_receive_callback([](const std::vector<uint8_t>& data) {
121 std::string msg(data.begin(), data.end());
122 std::cout << "[Client] Received: " << msg << std::endl;
123 });
124
125 client->set_error_callback([](std::error_code ec) {
126 std::cerr << "[Client] Error: " << ec.message() << std::endl;
127 });
128
129 // Send messages
130 std::vector<std::string> messages = {
131 "Hello UDP!",
132 "Datagrams preserve boundaries",
133 "Fast and lightweight",
134 };
135
136 for (const auto& msg : messages) {
137 std::vector<uint8_t> data(msg.begin(), msg.end());
138 std::cout << "[Client] Sending: " << msg << std::endl;
139
140 auto result = client->send(std::move(data));
141 if (result.is_err()) {
142 std::cerr << "[Client] Send failed: " << result.error().message << std::endl;
143 }
144
145 std::this_thread::sleep_for(std::chrono::milliseconds(500));
146 }
147
148 // Wait for final responses
149 std::this_thread::sleep_for(std::chrono::milliseconds(500));
150 g_done.store(true);
151}
152
153int main() {
154 std::cout << "=== UDP Echo Example ===" << std::endl;
155
156 try {
157 std::thread server_thread(run_server);
158 std::thread client_thread(run_client);
159
160 client_thread.join();
161 server_thread.join();
162
163 std::cout << "\n=== UDP echo example completed ===" << std::endl;
164 } catch (const std::exception& e) {
165 std::cerr << "Exception: " << e.what() << std::endl;
166 return 1;
167 }
168
169 return 0;
170}
Simplified facade for creating UDP clients and servers.
Definition udp_facade.h:72
Session interface representing an active client-server connection.
Main namespace for all Network System components.
void run_server()
Definition udp_echo.cpp:47
static std::atomic< bool > g_done
Definition udp_echo.cpp:45
void run_client()
Definition udp_echo.cpp:109
int main()
Definition udp_echo.cpp:153
Simplified facade for creating UDP clients and servers.