-
Notifications
You must be signed in to change notification settings - Fork 284
/
udp_echo_server.cpp
126 lines (99 loc) · 3.19 KB
/
udp_echo_server.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
//
// Created by Ivan Shynkarenka on 15.03.2017
//
#include "server/asio/service.h"
#include "server/asio/udp_server.h"
#include "system/cpu.h"
#include <iostream>
#include <OptionParser.h>
using namespace CppCommon;
using namespace CppServer::Asio;
class EchoServer : public UDPServer
{
public:
using UDPServer::UDPServer;
protected:
void onStarted() override
{
// Start receive datagrams
ReceiveAsync();
}
void onReceived(const asio::ip::udp::endpoint& endpoint, const void* buffer, size_t size) override
{
// Continue receive datagrams
if (size == 0)
{
ReceiveAsync();
return;
}
// Resend the message back to the client
SendAsync(endpoint, buffer, size);
}
void onSent(const asio::ip::udp::endpoint& endpoint, size_t sent) override
{
// Continue receive datagrams
ReceiveAsync();
}
void onError(int error, const std::string& category, const std::string& message) override
{
std::cout << "UDP server caught an error with code " << error << " and category '" << category << "': " << message << std::endl;
}
};
int main(int argc, char** argv)
{
auto parser = optparse::OptionParser().version("1.0.0.0");
parser.add_option("-p", "--port").dest("port").action("store").type("int").set_default(3333).help("Server port. Default: %default");
parser.add_option("-t", "--threads").dest("threads").action("store").type("int").set_default(CPU::PhysicalCores()).help("Count of working threads. Default: %default");
optparse::Values options = parser.parse_args(argc, argv);
// Print help
if (options.get("help"))
{
parser.print_help();
return 0;
}
// Server port
int port = options.get("port");
int threads = options.get("threads");
std::cout << "Server port: " << port << std::endl;
std::cout << "Working threads: " << threads << std::endl;
std::cout << std::endl;
// Create a new Asio service
auto service = std::make_shared<Service>(threads);
// Start the Asio service
std::cout << "Asio service starting...";
service->Start();
std::cout << "Done!" << std::endl;
// Create a new echo server
auto server = std::make_shared<EchoServer>(service, port);
server->SetupReuseAddress(true);
server->SetupReusePort(true);
// Start the server
std::cout << "Server starting...";
server->Start();
std::cout << "Done!" << std::endl;
std::cout << "Press Enter to stop the server or '!' to restart the server..." << std::endl;
// Perform text input
std::string line;
while (getline(std::cin, line))
{
if (line.empty())
break;
// Restart the server
if (line == "!")
{
std::cout << "Server restarting...";
server->Restart();
std::cout << "Done!" << std::endl;
continue;
}
}
// Stop the server
std::cout << "Server stopping...";
server->Stop();
std::cout << "Done!" << std::endl;
// Stop the Asio service
std::cout << "Asio service stopping...";
service->Stop();
std::cout << "Done!" << std::endl;
return 0;
}