Ticket #13477: socketPtr.cpp

File socketPtr.cpp, 5.4 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::shared_ptr<udp::socket> socketPtr;
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 : multicast_address(multicast_address),
48 multicast_port(multicast_port),
49 interval(interval),
50 showBroadcast(show)
51 {
52 UdpCore(io_service, show);
53 }
54
55 UdpCore(boost::asio::io_service& io_service, bool show = false)
56 : showBroadcast(show)
57 {
58 Initialize(io_service, show);
59 }
60
61 // destructor
62 ~UdpCore()
63 {
64 // show exit message
65 cout << "Exiting UDP Core." << endl;
66 }
67
68 // initialize
69 void Initialize(boost::asio::io_service& io_service, bool show = false)
70 {
71 if (initialize == false)
72 {
73 GetInfo();
74 }
75
76 boost::asio::ip::udp::endpoint endpoint(boost::asio::ip::address::from_string(multicast_address), multicast_port);
77 socketPtr = boost::make_shared<udp::socket>(boost::ref(io_service), endpoint.protocol());
78 socketPtr->set_option(boost::asio::ip::udp::socket::reuse_address(true)); // no need
79
80 thread_main = new boost::thread(boost::ref(*this));
81 thread_getsend = new boost::thread(&UdpCore::Callable_GetSend, this, interval, boost::ref(i_listen), boost::ref(message));
82 threads.add_thread(thread_getsend); // get/send thread
83 stop = false;
84 showBroadcast = show;
85 i_getsend = 0;
86 i_listen = 0;
87 i_main = 0;
88 i_message = 0;
89 message.clear();
90
91 initialize = true;
92 }
93
94 void GetInfo()
95 {
96 multicast_address = "192.168.0.255";
97 multicast_port = 13000;
98 interval = 500;
99 }
100
101 // start the threads
102 void Start()
103 {
104 // Wait till they are finished
105 threads.join_all();
106 }
107
108 // stop the threads
109 void Stop()
110 {
111 // warning message
112 cout << "Stopping all threads." << endl;
113
114 // signal the threads to stop (thread-safe)
115 stopMutex.lock();
116 stop = true;
117 stopMutex.unlock();
118
119 // wait for the threads to finish
120 thread_main->interrupt(); // in case not interrupted by operator()
121 threads.interrupt_all();
122 threads.join_all();
123
124 // close socket after everything closes
125 socketPtr->close();
126 }
127
128 void Callable_Listen(int interval, int& count)
129 {
130 while (!stop)
131 {
132 if (message != "")
133 socketPtr->async_send_to(boost::asio::buffer(message), endpoint, [this](boost::system::error_code ec, std::size_t /*length*/)
134 {
135 stopMutex.lock();
136 if (showBroadcast)
137 {
138 cout << i_message << " - " << message << endl; // show count
139 }
140 message.clear(); //clear after sending
141 stopMutex.unlock();
142 });
143 ++i_message;
144
145 // wait routine
146 boost::this_thread::sleep(boost::posix_time::millisec(interval));
147 boost::this_thread::interruption_point();
148 ++i_listen;
149 }
150 }
151
152 void Callable_GetSend(int interval, int& count, string& userInput)
153 {
154 while (!stop)
155 {
156 stopMutex.lock();
157 cout << "Callable_GetSend [" << count++ << "]. Enter message: ";
158 getline(cin, userInput);
159 if (message != "")
160 socketPtr->async_send_to(boost::asio::buffer(message), endpoint, [this](boost::system::error_code ec, std::size_t /*length*/)
161 {
162 if (showBroadcast)
163 {
164 cout << i_message << " - " << message << endl; // show count
165 }
166 message.clear(); //clear after sending
167 });
168 stopMutex.unlock();
169
170 // wait routine
171 boost::this_thread::sleep(boost::posix_time::millisec(interval));
172 boost::this_thread::interruption_point();
173 ++i_getsend;
174 ++i_message;
175 }
176 }
177
178 // Thread function
179 void operator () ()
180 {
181 while (!stop)
182 {
183 if (message == "STOP")
184 {
185 try
186 {
187 this->Stop();
188 }
189 catch (exception e)
190 {
191 cout << e.what() << endl;
192 }
193 }
194
195 boost::this_thread::sleep(boost::posix_time::millisec(interval));
196 boost::this_thread::interruption_point();
197 }
198 }
199
200 std::string make_daytime_string()
201 {
202 using namespace std; // For time_t, time and ctime;
203 time_t now = time(0);
204 std::string result = ctime(&now);
205 return result.erase(result.length() - 1, 1);
206 }
207
208 std::string some_string()
209 {
210 std::string result;
211 result = make_daytime_string();
212 return result;
213 }
214};
215
216int main()
217{
218 try
219 {
220 boost::asio::io_service io_service;
221 UdpCore mt(io_service, false);
222 mt.Start();
223 }
224 catch (std::exception& e)
225 {
226 std::cerr << "Exception: " << e.what() << "\n";
227 }
228}