Repository navigation
Expand file tree
/
Copy pathudp_receiver_demo.cpp
More file actions
185 lines (150 loc) · 5.02 KB
/
Copy pathudp_receiver_demo.cpp
File metadata and controls
185 lines (150 loc) · 5.02 KB
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
/**
* @fille
*
* @ingroup example_module
*
* @brief UDP reciever demo. Receive text messages from UDP broadcast agent.
*
* @author Thurman Gillespy
*
* @copyright (c) Thurman Gillespy
* 9/2/19
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*
* Sample make file. Assumes all repositories are in same directory
g++ -std=c++17 -Wall -Werror \
-I ../include \
-I ../../utility-rack/include/ \
-I ../../utility-rack/third_party/ \
-I ../../asio/asio/include/ \
udp_receiver_demo.cpp -lpthread -o udp_receive
*
*/
#include <iostream>
#include <cstdlib> // EXIT_SUCCESS
#include <string>
#include <thread>
#include <chrono>
#include <cassert>
#include "net_ip/net_ip.hpp"
#include "net_ip/net_entity.hpp"
#include "net_ip_component/worker.hpp"
#include "net_ip/io_type_decls.hpp"
using const_buf = asio::const_buffer;
using udp_io_interface = chops::net::udp_io_interface;
using endpoint = asio::ip::udp::endpoint;
using io_output = chops::net::udp_io_output;
const std::string PORT = "5005";
const std::string HELP_PRM = "-h";
const std::string ERRS_PRM = "-e";
auto print_useage = [] () {
const std::string USEAGE = \
"./udp_receive [-h] [-e] [port]\n"
" -h Print usage\n"
" -e Print error and system messages\n"
" port Default: " + PORT;
std::cout << USEAGE << std::endl;
};
bool process_args(int argc, char* argv[], bool& print_errors, std::string& port) {
int offset = 0;
if (argc >= 2 && argv[1] == HELP_PRM) {
print_useage();
return EXIT_FAILURE;
}
if (argc >= 2 && argv[1] == ERRS_PRM) {
print_errors = true;
offset = 1;
}
if (argc >= 2 + offset) {
// get port
port = argv[1 + offset];
}
// too many args?
if (argc >= 3 + offset) {
std::cout << "too many arguements" << std::endl;
print_useage();
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
int main(int argc, char* argv[]) {
std::string port = PORT;
const std::size_t MAX_BUF = 256;
bool print_errors = false;
bool first_msg = true;
chops::net::udp_io_interface udp_iof;
if (process_args(argc, argv, print_errors, port) == EXIT_FAILURE) {
return EXIT_FAILURE;
}
/**************************************/
/********** lambda callbacks **********/
/**************************************/
/******** message handler ********/
// receive text, display to console
auto msg_hndlr = [&first_msg] (const_buf buf, io_output io_out,
endpoint ep) {
// create string from buf
std::string s (static_cast<const char*> (buf.data()), buf.size());
// who we are getting the broadcast messages from
if (first_msg) {
std::cout << "UPD broadcasts from " << ep.address() << ":\n";
first_msg = false;
}
std::cout << "> " << s << std::endl;
return true;
};
/******** io state change handler ********/
auto io_state_chng_hndlr = [&]
(udp_io_interface iof, std::size_t n, bool flag) {
if (flag) {
auto e{iof.start_io(MAX_BUF, msg_hndlr)};
if (print_errors) {
std::cout << "io state change: start_io" << std::endl;
}
} else {
if (print_errors) {
std::cout << "io state change: stop_io" << std::endl;
}
// iof.stop_io();
}
};
/******** error handler ********/
auto err_func = [&print_errors] (chops::net::udp_io_interface iof, std::error_code err) {
if (print_errors) {
std::string err_text = err.category().name();
err_text += ": " + std::to_string(err.value()) + ", " +
err.message();
std::cerr << err_text << std::endl;
}
};
/********************************/
/********** start here **********/
/********************************/
std::cout << "chops-net-ip UDP receiver demo" << std::endl;
std::cout << " print errors and system messages: ";
std::cout << (print_errors ? "ON" : "OFF") << std::endl;
std::cout << " port: " << port << std::endl << std::endl;
std::cout << "Press Enter to exit program" << std::endl;
// work guard - handles @c std::thread and @c asio::io_context management
chops::net::worker wk;
wk.start();
// create @c net_ip instance
chops::net::net_ip udp_receive(wk.get_io_context());
// create a @c network_entitiy
chops::net::net_entity udp_ne;
udp_ne = udp_receive.make_udp_unicast(port.c_str());
assert(udp_ne.is_valid());
auto se {udp_ne.start(io_state_chng_hndlr, err_func)};
// pause for user input, then quit
std::string s;
getline(std::cin, s);
/******************************/
/********** shutdown **********/
/******************************/
auto stoperr {udp_ne.stop()};
// wk.stop();
wk.reset();
return EXIT_SUCCESS;
}