Ticket #13477: socket.cpp

File socket.cpp, 5.3 KB (added by nguyen.tnhoang@…, 5 years ago)
Line 
1#define _CRT_SECURE_NO_WARNINGS
2#include <ctime>
3#include <iostream>
4#include <string>
5#include <queue>
6#include <boost/array.hpp>
7#include <boost/bind.hpp>
8#include <boost/shared_ptr.hpp>
9#include <boost/asio.hpp>
10#include <boost/lexical_cast.hpp>
11#include <boost/thread.hpp>
12#include <boost/thread/thread.hpp>
13#include <boost/chrono.hpp>
14#include <boost/date_time/posix_time/posix_time.hpp>
15
16using boost::asio::ip::udp;
17using std::cout;
18using std::cin;
19using std::endl;
20using std::string;
21using namespace std;
22
23template<typename T>
24std::string toString(const T& value);
25std::string IntToString(const int& i);
26
27class UdpCore
28{
29private:
30 boost::asio::ip::udp::endpoint endpoint;
31 boost::asio::ip::udp::socket socket;
32
33 string multicast_address;
34 unsigned short multicast_port;
35 boost::thread_group threads; // thread group
36 boost::thread* thread_main; // main thread
37 boost::thread* thread_listen; // listen thread
38 boost::thread* thread_getsend; // get/send thread
39 boost::mutex stopMutex;
40 bool initialize = false;
41 bool stop, showBroadcast;
42 int i_getsend, i_listen, i_main, i_message, interval;
43 string message;
44public:
45 // constructor
46 UdpCore(boost::asio::io_service& io_service, std::string multicast_address, unsigned short multicast_port, int interval, bool show = false)
47 : endpoint(boost::asio::ip::address::from_string(multicast_address), multicast_port),
48 socket(io_service, endpoint.protocol()),
49 multicast_address(multicast_address),
50 multicast_port(multicast_port),
51 interval(interval),
52 showBroadcast(show)
53 {
54 Initialize(io_service, show);
55 }
56
57 ~UdpCore()
58 {
59 // show exit message
60 cout << "Exiting UDP Core." << endl;
61 }
62
63 // initialize
64 void Initialize(boost::asio::io_service& io_service, bool show = false)
65 {
66 if (initialize == false)
67 {
68 GetInfo();
69 }
70
71 boost::asio::ip::udp::endpoint endpoint(boost::asio::ip::make_address(multicast_address), multicast_port);
72 boost::asio::ip::udp::socket socket(io_service, endpoint.protocol());
73 socket.set_option(boost::asio::ip::udp::socket::reuse_address(true)); // no need
74
75 thread_main = new boost::thread(boost::ref(*this));
76 thread_getsend = new boost::thread(&UdpCore::Callable_GetSend, this, interval, boost::ref(i_listen), boost::ref(message));
77 threads.add_thread(thread_getsend); // get/send thread
78 stop = false;
79 showBroadcast = show;
80 i_getsend = 0;
81 i_listen = 0;
82 i_main = 0;
83 i_message = 0;
84 message.clear();
85
86 initialize = true;
87 }
88
89 void GetInfo()
90 {
91 multicast_address = "192.168.0.255";
92 multicast_port = 13000;
93 interval = 500;
94 }
95
96 // start the threads
97 void Start()
98 {
99 // Wait till they are finished
100 threads.join_all();
101 }
102
103 // stop the threads
104 void Stop()
105 {
106 // warning message
107 cout << "Stopping all threads." << endl;
108
109 // signal the threads to stop (thread-safe)
110 stopMutex.lock();
111 stop = true;
112 stopMutex.unlock();
113
114 // wait for the threads to finish
115 thread_main->interrupt(); // in case not interrupted by operator()
116 threads.interrupt_all();
117 threads.join_all();
118
119 // close socket after everything closes
120 socket.close();
121 }
122
123 void Callable_Listen(int interval, int& count)
124 {
125 while (!stop)
126 {
127 if (message != "")
128 socket.async_send_to(boost::asio::buffer(message), endpoint, [this](boost::system::error_code ec, std::size_t /*length*/)
129 {
130 stopMutex.lock();
131 if (showBroadcast)
132 {
133 cout << i_message << " - " << message << endl; // show count
134 }
135 message.clear(); //clear after sending
136 stopMutex.unlock();
137 });
138 ++i_message;
139
140 // wait routine
141 boost::this_thread::sleep(boost::posix_time::millisec(interval));
142 boost::this_thread::interruption_point();
143 ++i_listen;
144 }
145 }
146
147 void Callable_GetSend(int interval, int& count, string& userInput)
148 {
149 while (!stop)
150 {
151 stopMutex.lock();
152 cout << "Callable_GetSend [" << count++ << "]. Enter message: ";
153 getline(cin, userInput);
154 if (message != "")
155 socket.async_send_to(boost::asio::buffer(message), endpoint, [this](boost::system::error_code ec, std::size_t /*length*/)
156 {
157 if (showBroadcast)
158 {
159 cout << i_message << " - " << message << endl; // show count
160 }
161 message.clear(); //clear after sending
162 });
163 stopMutex.unlock();
164
165 // wait routine
166 boost::this_thread::sleep(boost::posix_time::millisec(interval));
167 boost::this_thread::interruption_point();
168 ++i_getsend;
169 ++i_message;
170 }
171 }
172
173 // Thread function
174 void operator () ()
175 {
176 while (!stop)
177 {
178 if (message == "STOP")
179 {
180 try
181 {
182 this->Stop();
183 }
184 catch (exception e)
185 {
186 cout << e.what() << endl;
187 }
188 }
189
190 boost::this_thread::sleep(boost::posix_time::millisec(interval));
191 boost::this_thread::interruption_point();
192 }
193 }
194
195 std::string make_daytime_string()
196 {
197 using namespace std; // For time_t, time and ctime;
198 time_t now = time(0);
199 std::string result = ctime(&now);
200 return result.erase(result.length() - 1, 1);
201 }
202
203 std::string some_string()
204 {
205 std::string result;
206 result = make_daytime_string();
207 return result;
208 }
209};
210
211int main()
212{
213 try
214 {
215 boost::asio::io_service io_service;
216 UdpCore mt(io_service, "192.168.0.255", 13000, 5000, false);
217 mt.Start();
218 }
219 catch (std::exception& e)
220 {
221 std::cerr << "Exception: " << e.what() << "\n";
222 }
223}