Network System 0.1.1
High-performance modular networking library for scalable client-server applications
Loading...
Searching...
No Matches
tcp_echo_server.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 <csignal>
37#include <iostream>
38#include <map>
39#include <mutex>
40#include <string>
41#include <thread>
42
43using namespace kcenon::network;
44
45// Global flag for graceful shutdown
46static std::atomic<bool> g_running{true};
47
48void signal_handler(int /*signum*/) {
49 g_running.store(false);
50}
51
52int main() {
53 std::cout << "=== TCP Echo Server Example ===" << std::endl;
54
55 // Register signal handler for graceful shutdown
56 std::signal(SIGINT, signal_handler);
57 std::signal(SIGTERM, signal_handler);
58
59 // Create TCP facade and server
61 constexpr uint16_t port = 9000;
62
63 auto server = tcp.create_server({
64 .port = port,
65 .server_id = "EchoServer",
66 });
67
68 // Thread-safe session storage for echoing data back
69 std::mutex sessions_mutex;
70 std::map<std::string, std::shared_ptr<interfaces::i_session>> sessions;
71
72 // Track new connections
73 server->set_connection_callback(
74 [&sessions, &sessions_mutex](std::shared_ptr<interfaces::i_session> session) {
75 std::lock_guard<std::mutex> lock(sessions_mutex);
76 std::string id(session->id());
77 sessions[id] = session;
78 std::cout << "[Server] Client connected: " << id << std::endl;
79 });
80
81 // Track disconnections
82 server->set_disconnection_callback(
83 [&sessions, &sessions_mutex](std::string_view session_id) {
84 std::lock_guard<std::mutex> lock(sessions_mutex);
85 sessions.erase(std::string(session_id));
86 std::cout << "[Server] Client disconnected: " << session_id << std::endl;
87 });
88
89 // Echo received data back to the sender
90 server->set_receive_callback(
91 [&sessions, &sessions_mutex](std::string_view session_id,
92 const std::vector<uint8_t>& data) {
93 std::string message(data.begin(), data.end());
94 std::cout << "[Server] Received from " << session_id << ": " << message
95 << std::endl;
96
97 // Find the session and echo data back
98 std::shared_ptr<interfaces::i_session> session;
99 {
100 std::lock_guard<std::mutex> lock(sessions_mutex);
101 auto it = sessions.find(std::string(session_id));
102 if (it != sessions.end()) {
103 session = it->second;
104 }
105 }
106
107 if (session) {
108 auto result = session->send(std::vector<uint8_t>(data));
109 if (result.is_err()) {
110 std::cerr << "[Server] Echo failed: " << result.error().message
111 << std::endl;
112 }
113 }
114 });
115
116 // Log errors
117 server->set_error_callback(
118 [](std::string_view session_id, std::error_code ec) {
119 std::cerr << "[Server] Error on " << session_id << ": " << ec.message()
120 << std::endl;
121 });
122
123 // Start the server
124 auto result = server->start(port);
125 if (result.is_err()) {
126 std::cerr << "Failed to start server: " << result.error().message << std::endl;
127 return 1;
128 }
129
130 std::cout << "[Server] Listening on port " << port << std::endl;
131 std::cout << "[Server] Press Ctrl+C to stop." << std::endl;
132
133 // Main loop: wait until shutdown signal
134 while (g_running.load()) {
135 std::this_thread::sleep_for(std::chrono::milliseconds(100));
136 }
137
138 // Graceful shutdown
139 std::cout << "\n[Server] Shutting down..." << std::endl;
140 auto stop_result = server->stop();
141 if (stop_result.is_err()) {
142 std::cerr << "[Server] Stop error: " << stop_result.error().message << std::endl;
143 }
144
145 std::cout << "[Server] Stopped." << std::endl;
146 return 0;
147}
Simplified facade for creating TCP clients and servers.
Definition tcp_facade.h:95
Session interface representing an active client-server connection.
Main namespace for all Network System components.
void signal_handler(int)
static std::atomic< bool > g_running
int main()
Simplified facade for creating TCP clients and servers.