-
Notifications
You must be signed in to change notification settings - Fork 297
/
Copy pathtcp_echo_server.cpp
126 lines (99 loc) · 3.3 KB
/
tcp_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/tcp_server.h"
#include "system/cpu.h"
#include <iostream>
#include <OptionParser.h>
using namespace CppCommon;
using namespace CppServer::Asio;
class EchoSession : public TCPSession
{
public:
using TCPSession::TCPSession;
protected:
void onReceived(const void* buffer, size_t size) override
{
// Resend the message back to the client
SendAsync(buffer, size);
}
void onError(int error, const std::string& category, const std::string& message) override
{
std::cout << "TCP session caught an error with code " << error << " and category '" << category << "': " << message << std::endl;
}
};
class EchoServer : public TCPServer
{
public:
using TCPServer::TCPServer;
protected:
std::shared_ptr<TCPSession> CreateSession(const std::shared_ptr<TCPServer>& server) override
{
return std::make_shared<EchoSession>(server);
}
protected:
void onError(int error, const std::string& category, const std::string& message) override
{
std::cout << "TCP 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(1111).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->SetupNoDelay(true);
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;
}