Skip to content

Commit ad0a22c

Browse files
committedMar 17, 2025
The final cut
Correct error handling Update copyright notice
1 parent a171a77 commit ad0a22c

13 files changed

+162
-159
lines changed
 

‎CMakeLists.txt

+11-1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ target_link_libraries(
6262
PUBLIC Boost::asio
6363
)
6464

65+
# add_executable(async_tcp_client_v20 async_tcp_client_v20.cpp)
66+
# target_link_libraries(async_tcp_client_v20 PUBLIC Boost::asio)
67+
68+
# add_executable(async_tcp_client async_tcp_client.cpp)
69+
# target_link_libraries(async_tcp_client PUBLIC Boost::asio)
70+
6571
# add_executable(blocking_tcp_echo_server blocking_tcp_echo_server.cpp)
6672
# target_link_libraries(blocking_tcp_echo_server PUBLIC Boost::asio)
6773

@@ -79,5 +85,9 @@ if(APPLE)
7985
endif()
8086

8187
add_executable(rrcp_async_tcp_client rrcp_async_tcp_client.cpp)
82-
target_link_libraries(rrcp_async_tcp_client PRIVATE rrcp_helper PUBLIC Boost::asio)
88+
target_link_libraries(
89+
rrcp_async_tcp_client
90+
PRIVATE rrcp_helper
91+
PUBLIC Boost::asio
92+
)
8393
# TODO: add_test(NAME rrcp_async_tcp_client COMMAND echo | rrcp_async_tcp_client localhost 8001)

‎GNUmakefile

+2-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ test: all
4545
cat rrcp.txt | build/rrcp_client localhost 8000
4646
cat rrcp.txt | build/rrcp_async_tcp_client localhost 8000
4747
cat rrcp.txt | build/async_tcp_echo_client localhost 8000
48-
#TODO: echo | build/async_tcp_client localhost 8001
48+
-build/async_tcp_echo_client localhost
49+
-echo | build/async_tcp_echo_client localhost 8001
4950
cat rrcp.txt | build/blocking_tcp_echo_client localhost 8000
5051
ctest --test-dir build
5152
-killall async_tcp_echo_server

‎async_tcp_client.cpp

+34-27
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
// Distributed under the Boost Software License, Version 1.0. (See accompanying
88
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
99
//
10+
// Moderniced from Claus Klein and ChatGPT
1011

1112
#include <boost/asio/buffer.hpp>
1213
#include <boost/asio/io_context.hpp>
@@ -20,14 +21,12 @@
2021
#include <exception>
2122
#include <functional>
2223
#include <iostream>
24+
#include <memory>
2325
#include <string>
2426
#include <utility>
2527

2628
using boost::asio::steady_timer;
2729
using boost::asio::ip::tcp;
28-
using std::placeholders::_1; // NOLINT
29-
using std::placeholders::_2; // NOLINT
30-
3130
using namespace std::chrono_literals;
3231

3332
//
@@ -90,7 +89,7 @@ using namespace std::chrono_literals;
9089
// newline character) every 10 seconds. In this example, no deadline is applied
9190
// to message sending.
9291
//
93-
class client
92+
class client : public std::enable_shared_from_this< client >
9493
{
9594
public:
9695
explicit client(boost::asio::io_context& io_context)
@@ -135,9 +134,8 @@ class client
135134
deadline_.expires_after(60s);
136135

137136
// Start the asynchronous connect operation.
138-
socket_.async_connect(endpoint_iter->endpoint(), std::bind(&client::handle_connect, this, _1, endpoint_iter));
139-
// FIXME: [this, endpoint_iter](auto && PH1) {
140-
// handle_connect(std::forward<decltype(PH1)>(PH1), endpoint_iter); });
137+
socket_.async_connect(endpoint_iter->endpoint(),
138+
[this, endpoint_iter](const boost::system::error_code& error) { handle_connect(error, endpoint_iter); });
141139
}
142140
else
143141
{
@@ -158,7 +156,7 @@ class client
158156
// time then the timeout handler must have run first.
159157
if (!socket_.is_open())
160158
{
161-
std::cout << "Connect timed out\n";
159+
std::cerr << "Connect timed out\n";
162160

163161
// Try the next available endpoint.
164162
start_connect(++endpoint_iter);
@@ -167,7 +165,7 @@ class client
167165
// Check if the connect operation failed before the deadline expired.
168166
else if (error)
169167
{
170-
std::cout << "Connect error: " << error.message() << "\n";
168+
std::cerr << "Connect error: " << error.message() << "\n";
171169

172170
// We need to close the socket used in the previous connection
173171
// attempt before starting a new one.
@@ -192,15 +190,19 @@ class client
192190

193191
void start_read()
194192
{
193+
if (stopped_)
194+
{
195+
return;
196+
}
197+
195198
// Set a deadline for the read operation.
196199
deadline_.expires_after(30s);
197200

201+
auto self(shared_from_this());
202+
198203
// Start an asynchronous operation to read a newline-delimited message.
199-
boost::asio::async_read_until(
200-
socket_, boost::asio::dynamic_buffer(input_buffer_), '\n', std::bind(&client::handle_read, this, _1, _2));
201-
// FIXME: [this](auto && PH1, auto && PH2) {
202-
// handle_read(std::forward<decltype(PH1)>(PH1),
203-
// std::forward<decltype(PH2)>(PH2)); });
204+
boost::asio::async_read_until(socket_, boost::asio::dynamic_buffer(input_buffer_), '\n',
205+
[this, self](const boost::system::error_code& error, std::size_t n) { handle_read(error, n); });
204206
}
205207

206208
void handle_read(const boost::system::error_code& error, std::size_t n)
@@ -213,7 +215,7 @@ class client
213215
if (!error)
214216
{
215217
// Extract the newline-delimited message from the buffer.
216-
std::string const line(input_buffer_.substr(0, n - 1));
218+
std::string const line = input_buffer_.substr(0, n - 1); // NOTE: w/o '\n'
217219
input_buffer_.erase(0, n);
218220

219221
// Empty messages are heartbeats and so ignored.
@@ -226,7 +228,7 @@ class client
226228
}
227229
else
228230
{
229-
std::cout << "Error on receive: " << error.message() << "\n";
231+
std::cerr << "Error on receive: " << error.message() << "\n";
230232

231233
stop();
232234
}
@@ -239,10 +241,14 @@ class client
239241
return;
240242
}
241243

244+
std::string message{'\n'};
245+
std::print(stderr, "Sending: {}\n", "hartbeat");
246+
247+
auto self(shared_from_this());
248+
242249
// Start an asynchronous operation to send a heartbeat message.
243-
boost::asio::async_write(socket_, boost::asio::buffer("\n", 1), std::bind(&client::handle_write, this, _1));
244-
// XXX [this](const boost::system::error_code& /*e*/, PH1) {
245-
// handle_write(std::forward<decltype(PH1)>(PH1)); });
250+
boost::asio::async_write(socket_, boost::asio::buffer(message),
251+
[this, self](const boost::system::error_code& error, std::size_t) { handle_write(error); });
246252
}
247253

248254
void handle_write(const boost::system::error_code& error)
@@ -256,12 +262,11 @@ class client
256262
{
257263
// Wait 10 seconds before sending the next heartbeat.
258264
heartbeat_timer_.expires_after(10s);
259-
// cpp11: heartbeat_timer_.async_wait(std::bind(&client::start_write, this));
260265
heartbeat_timer_.async_wait([this](const boost::system::error_code& /*e*/) { start_write(); });
261266
}
262267
else
263268
{
264-
std::cout << "Error on heartbeat: " << error.message() << "\n";
269+
std::cerr << "Error on heartbeat: " << error.message() << "\n";
265270

266271
stop();
267272
}
@@ -289,12 +294,13 @@ class client
289294
deadline_.expires_at(steady_timer::time_point::max());
290295
}
291296

297+
auto self(shared_from_this());
298+
292299
// Put the actor back to sleep.
293-
// cpp11: deadline_.async_wait(std::bind(&client::check_deadline, this));
294-
deadline_.async_wait([this](const boost::system::error_code& /*e*/) { check_deadline(); });
300+
deadline_.async_wait([this, self](const boost::system::error_code& /*e*/) { check_deadline(); });
295301
}
296302

297-
bool stopped_ = false;
303+
bool stopped_{false};
298304
tcp::resolver::results_type endpoints_;
299305
tcp::socket socket_;
300306
std::string input_buffer_;
@@ -313,10 +319,11 @@ auto main(int argc, char* argv[]) -> int
313319
}
314320

315321
boost::asio::io_context io_context;
316-
tcp::resolver r(io_context);
317-
client c(io_context);
322+
tcp::resolver resolver(io_context);
323+
324+
auto c = std::make_shared< client >(io_context);
318325

319-
c.start(r.resolve(argv[1], argv[2]));
326+
c->start(resolver.resolve(argv[1], argv[2]));
320327

321328
io_context.run();
322329
}

‎async_tcp_client_v20.cpp

+5-3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
*
77
* Distributed under the Boost Software License, Version 1.0. (See accompanying
88
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9+
*
10+
* Moderniced from Claus Klein and ChatGPT
911
***/
1012

1113
#include <boost/asio/buffer.hpp>
@@ -15,7 +17,7 @@
1517
#include <boost/asio/steady_timer.hpp>
1618
#include <boost/asio/write.hpp>
1719
#include <boost/system/detail/error_code.hpp>
18-
#include <chrono>
20+
#include <chrono> // NOLINT(misc-include-cleaner)
1921
#include <cstddef>
2022
#include <exception>
2123
#include <format>
@@ -238,7 +240,7 @@ class client : public std::enable_shared_from_this< client >
238240
// Wait 10 seconds before sending the next heartbeat.
239241
heartbeat_timer_.cancel();
240242
heartbeat_timer_.expires_after(10s);
241-
heartbeat_timer_.async_wait([this](const boost::system::error_code&) { start_write(); });
243+
heartbeat_timer_.async_wait([this](const boost::system::error_code& /*e*/) { start_write(); });
242244
}
243245
else
244246
{
@@ -273,7 +275,7 @@ class client : public std::enable_shared_from_this< client >
273275
auto self(shared_from_this());
274276

275277
// Put the actor back to sleep.
276-
deadline_.async_wait([this, self](const boost::system::error_code&) { check_deadline(); });
278+
deadline_.async_wait([this, self](const boost::system::error_code& /*e*/) { check_deadline(); });
277279
}
278280

279281
bool stopped_{false};

‎async_tcp_echo_client.cpp

+17-5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
/***
2+
* async_tcp_echo_client.cpp
3+
* ~~~~~~~~~~~~~~~~~~~~~~~~~
4+
*
5+
* Copyright (c) 2003-2024 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6+
*
7+
* Distributed under the Boost Software License, Version 1.0. (See accompanying
8+
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9+
*
10+
* Moderniced from Claus Klein and ChatGPT
11+
***/
12+
113
#include <fmt/format.h>
214

315
#include <boost/algorithm/string/trim.hpp>
@@ -137,18 +149,18 @@ class AsynchronousTCPClient : public std::enable_shared_from_this< AsynchronousT
137149
});
138150
}
139151

140-
boost::asio::async_read_until(socket_, boost::asio::dynamic_buffer(data_), CR,
152+
boost::asio::async_read_until(socket_, boost::asio::dynamic_buffer(data_), STOP,
141153
[this, self](boost::system::error_code ec, std::size_t length)
142154
{
143155
timer_.cancel();
144156
if (!ec)
145157
{
146-
std::string response = esc2char(data_.substr(1, length)); // NOTE: w/o LF!
158+
std::string response = esc2char(data_.substr(1, length)); // NOTE: w/o START!
147159

148160
// NOTE: data_.erase(0, length); is used instead of data_.clear() because:
149161

150162
// - Partial Data Handling: The async_read_until() function reads
151-
// data up to the delimiter (CR) but doesn’t guarantee it consumes
163+
// data up to the delimiter (STOP) but doesn’t guarantee it consumes
152164
// all the data in the socket.
153165
// There might be extra data left in the buffer after the delimiter!
154166

@@ -209,8 +221,8 @@ auto main(int argc, char* argv[]) -> int
209221
}
210222

211223
std::string command = char2esc(line);
212-
command.insert(0, 1, LF);
213-
command += CR;
224+
command.insert(0, 1, START);
225+
command += STOP;
214226

215227
client->write(command);
216228
}

‎async_tcp_echo_server.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
// Distributed under the Boost Software License, Version 1.0. (See accompanying
88
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
99
//
10+
// Moderniced from Claus Klein and ChatGPT
1011

1112
#include <array>
1213
#include <boost/asio/signal_set.hpp>

‎blocking_tcp_echo_client.cpp

+4-3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
// Distributed under the Boost Software License, Version 1.0. (See accompanying
88
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
99
//
10+
// Moderniced from Claus Klein and ChatGPT
1011

1112
#include <boost/algorithm/string/trim.hpp>
1213
#include <boost/asio/buffer.hpp>
@@ -60,8 +61,8 @@ auto main(int argc, char* argv[]) -> int
6061

6162
// TODO: check boost::system::error_code ec;
6263
std::string command = char2esc(line);
63-
command.insert(0, 1, LF);
64-
command += CR;
64+
command.insert(0, 1, START);
65+
command += STOP;
6566
boost::asio::write(s, boost::asio::buffer(command.c_str(), command.length()));
6667

6768
// TODO: wait for endchar with timeout!
@@ -71,7 +72,7 @@ auto main(int argc, char* argv[]) -> int
7172

7273
do
7374
{
74-
size_t const reply_length = boost::asio::read_until(s, sb2, CR); // NOLINT(clang-analyzer-deadcode.DeadStores)
75+
size_t const reply_length = boost::asio::read_until(s, sb2, STOP); // NOLINT(clang-analyzer-deadcode.DeadStores)
7576
std::string const response = esc2char(data);
7677
if (response.empty())
7778
{

‎blocking_tcp_echo_server.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
// Distributed under the Boost Software License, Version 1.0. (See accompanying
88
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
99
//
10+
// Moderniced from Claus Klein and ChatGPT
1011

1112
#include <array>
1213
#include <boost/asio/buffer.hpp>

‎rrcp_async_tcp_client.cpp

+79-113
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
/***
2+
* rrcp_async_tcp_client.cpp
3+
* ~~~~~~~~~~~~~~~~~~~~~~~~~
4+
*
5+
* Copyright (c) 2003-2024 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6+
*
7+
* Distributed under the Boost Software License, Version 1.0. (See accompanying
8+
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9+
*
10+
* Moderniced from Claus Klein and ChatGPT
11+
***/
12+
113
#include <boost/asio.hpp>
214
#include <boost/system/error_code.hpp>
315
#include <chrono>
@@ -7,106 +19,38 @@
719
#include <string_view>
820
#include <thread>
921

10-
constexpr char ESC = 0x1B;
11-
constexpr char REPLACE_LF = 0x01;
12-
constexpr char REPLACE_CR = 0x02;
13-
constexpr char REPLACE_ESC = 0x03;
22+
#include "rrcp_helper.hpp"
1423

1524
using boost::asio::ip::tcp;
1625
using namespace std::chrono_literals;
1726

18-
auto esc2char(std::string_view data) -> std::string
19-
{
20-
std::string message;
21-
auto len = data.size();
22-
for (size_t i = 0; i < len; ++i)
23-
{
24-
char c = data[i];
25-
26-
if (c == '\r')
27-
{
28-
return message;
29-
}
30-
31-
if (c == ESC)
32-
{
33-
if (i == len - 1)
34-
{
35-
throw std::runtime_error("esc2char: Error - message ends with escape character!");
36-
}
37-
38-
char next = data[++i];
39-
switch (next)
40-
{
41-
case REPLACE_LF:
42-
c = '\n';
43-
break;
44-
case REPLACE_CR:
45-
c = '\r';
46-
break;
47-
case REPLACE_ESC:
48-
c = ESC;
49-
break;
50-
default:
51-
throw std::runtime_error("esc2char: Error - unexpected ESC character!");
52-
}
53-
}
54-
55-
message.push_back(c);
56-
}
57-
return message;
58-
}
59-
60-
auto char2esc(std::string_view data) -> std::string
61-
{
62-
std::string message;
63-
for (char c : data)
64-
{
65-
switch (c)
66-
{
67-
case '\n':
68-
message.push_back(ESC);
69-
message.push_back(REPLACE_LF);
70-
break;
71-
case '\r':
72-
message.push_back(ESC);
73-
message.push_back(REPLACE_CR);
74-
break;
75-
case ESC:
76-
message.push_back(ESC);
77-
message.push_back(REPLACE_ESC);
78-
break;
79-
default:
80-
message.push_back(c);
81-
break;
82-
}
83-
}
84-
return message;
85-
}
86-
87-
class client : public std::enable_shared_from_this< client >
27+
class rrcp_client : public std::enable_shared_from_this< rrcp_client >
8828
{
8929
public:
90-
client(boost::asio::io_context& io_context) : socket_(io_context), deadline_(io_context), heartbeat_timer_(io_context)
30+
explicit rrcp_client(boost::asio::io_context& io_context)
31+
: socket_(io_context), deadline_(io_context), heartbeat_timer_(io_context)
9132
{
9233
deadline_.expires_at(boost::asio::steady_timer::time_point::max());
9334
}
9435

95-
void start(tcp::resolver::results_type endpoints)
36+
void start(const tcp::resolver::results_type& endpoints)
9637
{
38+
deadline_.expires_after(3s);
39+
check_deadline();
40+
9741
boost::asio::async_connect(socket_, endpoints,
9842
[self = shared_from_this()](const boost::system::error_code& ec, const tcp::endpoint&)
9943
{
10044
if (!ec)
10145
{
10246
std::cout << "Connected to server.\n";
10347
self->read();
104-
self->start_heartbeat();
105-
self->check_deadline();
48+
self->send_heartbeat();
10649
}
10750
else
10851
{
109-
std::cerr << "Failed to connect: " << ec.message() << '\n';
52+
// FIXME: this aborts! CK
53+
throw std::runtime_error("Failed to connect: " + ec.message());
11054
}
11155
});
11256
}
@@ -116,9 +60,12 @@ class client : public std::enable_shared_from_this< client >
11660
std::string message;
11761
while (std::getline(std::cin, message))
11862
{
119-
if (stopped_) return;
63+
if (stopped_)
64+
{
65+
return;
66+
}
12067

121-
message = '\n' + char2esc(message) + '\r';
68+
message = START + char2esc(message) + STOP;
12269
boost::asio::async_write(socket_, boost::asio::buffer(message),
12370
[self = shared_from_this()](const boost::system::error_code& ec, std::size_t)
12471
{
@@ -128,25 +75,27 @@ class client : public std::enable_shared_from_this< client >
12875
self->stop();
12976
}
13077
});
78+
13179
deadline_.expires_after(3s);
13280
}
13381
}
13482

13583
void read()
13684
{
137-
boost::asio::async_read_until(socket_, boost::asio::dynamic_buffer(input_buffer_), '\r',
85+
boost::asio::async_read_until(socket_, boost::asio::dynamic_buffer(input_buffer_), STOP,
13886
[self = shared_from_this()](const boost::system::error_code& ec, std::size_t length)
13987
{
14088
if (!ec)
14189
{
142-
std::string line = esc2char(self->input_buffer_.substr(0, length - 1));
90+
std::string const line = esc2char(self->input_buffer_.substr(1, length - 1)); // w/o START, STOP
14391
self->input_buffer_.erase(0, length);
144-
// XXX if (line != "GPing")
92+
93+
if (!line.starts_with("gPing"))
14594
{
146-
std::cout << "Server: " << line << '\n';
95+
std::cout << line << '\n';
14796
}
14897
self->read();
149-
self->deadline_.expires_after(3s);
98+
self->deadline_.expires_after(13s);
15099
}
151100
else
152101
{
@@ -156,19 +105,33 @@ class client : public std::enable_shared_from_this< client >
156105
});
157106
}
158107

159-
void start_heartbeat()
108+
void stop()
109+
{
110+
std::cerr << "stop called, disconnecting...\n";
111+
stopped_ = true;
112+
boost::system::error_code ec;
113+
socket_.close(ec);
114+
heartbeat_timer_.cancel();
115+
deadline_.cancel();
116+
}
117+
118+
private:
119+
void send_heartbeat()
160120
{
161-
if (stopped_) return;
121+
if (stopped_)
122+
{
123+
return;
124+
}
162125

163-
std::string heartbeat_message{'\n' + char2esc("GPing") + '\r'};
126+
std::string heartbeat_message{START + char2esc("M:Utility GPing") + STOP};
164127
std::cerr << "Send heartbeat: " << heartbeat_message << '\n';
165128
boost::asio::async_write(socket_, boost::asio::buffer(heartbeat_message),
166129
[self = shared_from_this()](const boost::system::error_code& ec, std::size_t)
167130
{
168131
if (!ec)
169132
{
170133
self->heartbeat_timer_.expires_after(10s);
171-
self->heartbeat_timer_.async_wait([self](const boost::system::error_code&) { self->start_heartbeat(); });
134+
self->heartbeat_timer_.async_wait([self](const boost::system::error_code&) { self->send_heartbeat(); });
172135
}
173136
else
174137
{
@@ -180,7 +143,10 @@ class client : public std::enable_shared_from_this< client >
180143

181144
void check_deadline()
182145
{
183-
if (stopped_) return;
146+
if (stopped_)
147+
{
148+
return;
149+
}
184150

185151
if (deadline_.expiry() <= boost::asio::steady_timer::clock_type::now())
186152
{
@@ -192,41 +158,41 @@ class client : public std::enable_shared_from_this< client >
192158
deadline_.async_wait([self = shared_from_this()](const boost::system::error_code&) { self->check_deadline(); });
193159
}
194160

195-
void stop()
196-
{
197-
std::cerr << "stop called, disconnecting...\n";
198-
stopped_ = true;
199-
boost::system::error_code ec;
200-
socket_.close(ec);
201-
heartbeat_timer_.cancel();
202-
deadline_.cancel();
203-
}
204-
205-
private:
206161
tcp::socket socket_;
207162
boost::asio::steady_timer deadline_, heartbeat_timer_;
208163
std::string input_buffer_;
209164
bool stopped_{false};
210165
};
211166

212-
int main(int argc, char* argv[])
167+
auto main(int argc, char* argv[]) -> int
213168
{
214169
if (argc != 3)
215170
{
216171
std::cerr << "Usage: " << argv[0] << " <host> <port>\n";
217-
return 1;
172+
return EXIT_FAILURE;
218173
}
219174

220-
boost::asio::io_context io_context;
221-
tcp::resolver resolver(io_context);
175+
try
176+
{
177+
boost::asio::io_context io_context;
178+
tcp::resolver resolver(io_context);
179+
180+
auto c = std::make_shared< rrcp_client >(io_context);
181+
c->start(resolver.resolve(argv[1], argv[2]));
222182

223-
auto c = std::make_shared< client >(io_context);
224-
c->start(resolver.resolve(argv[1], argv[2]));
183+
std::thread io_thread([&io_context]() { io_context.run(); });
225184

226-
std::thread io_thread([&io_context]() { io_context.run(); });
227-
c->write();
228-
c->stop();
229-
io_thread.join();
185+
std::this_thread::sleep_for(3s); // NOLINT(misc-include-cleaner)
186+
c->write();
187+
188+
c->stop();
189+
io_thread.join();
190+
}
191+
catch (std::exception& e)
192+
{
193+
std::cerr << "Exception: " << e.what() << "\n";
194+
return EXIT_FAILURE;
195+
}
230196

231-
return 0;
197+
return EXIT_SUCCESS;
232198
}

‎rrcp_client.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
// Distributed under the Boost Software License, Version 1.0. (See accompanying
88
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
99
//
10+
// Moderniced from Claus Klein and ChatGPT
1011

1112
#include <boost/algorithm/string/trim.hpp>
1213
#include <boost/asio/buffer.hpp>

‎rrcp_helper.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ auto esc2char(std::string_view data) -> std::string
1818
{
1919
char c = data[i];
2020

21-
if (c == '\r')
21+
if (c == STOP)
2222
{
2323
return message;
2424
}

‎rrcp_helper.hpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
#include <string>
44
#include <string_view>
55

6-
constexpr const char LF{0x0A}; // \n
7-
constexpr const char CR{0x0D}; // \r
6+
constexpr const char START{0x0A}; // \n
7+
constexpr const char STOP{0x0D}; // \r
88

99
/**
10-
* @brief Gets the message between <LF>message<CR> and
11-
* replaces the escape sequences for LF and CR
10+
* @brief Gets the message between <START>message<STOP> and
11+
* replaces the escape sequences for START and STOP
1212
*
1313
*
1414
* @param data: read from socket
@@ -18,7 +18,7 @@ constexpr const char CR{0x0D}; // \r
1818
extern auto esc2char(std::string_view data) -> std::string;
1919

2020
/**
21-
* @brief Replaces LF, CR with Escape sequence
21+
* @brief Replaces START, STOP with Escape sequence
2222
*
2323
* @param data: data to send
2424
*

‎timer.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
// Distributed under the Boost Software License, Version 1.0. (See accompanying
88
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
99
//
10+
// Moderniced from Claus Klein and ChatGPT
1011

1112
#include <boost/asio/io_context.hpp>
1213
#include <boost/asio/steady_timer.hpp>

0 commit comments

Comments
 (0)
Please sign in to comment.