socket_server.cpp
Go to the documentation of this file.
1 
9 /*****************************************************************************
10 ** Platform Check
11 *****************************************************************************/
12 
13 #include <ecl/config/ecl.hpp>
14 
15 #ifdef ECL_IS_POSIX
16 #ifndef ECL_IS_MAC
17 
18 /*****************************************************************************
19 ** Includes
20 *****************************************************************************/
21 
22 #include <iostream>
23 #include <ecl/command_line.hpp>
24 #include <ecl/threads/thread.hpp>
25 #include <ecl/time/sleep.hpp>
26 #include <ecl/time/timestamp.hpp>
28 #include <ecl/devices/socket.hpp>
29 #include <ecl/formatters.hpp>
30 
31 /*****************************************************************************
32 ** Namespaces
33 *****************************************************************************/
34 
35 namespace ecl {
36 namespace demos {
37 
38 /*****************************************************************************
39 ** Using
40 *****************************************************************************/
41 
42 using ecl::CmdLine;
43 using ecl::ValueArg;
44 using ecl::SwitchArg;
45 using ecl::ArgException;
47 using ecl::SocketServer;
48 using ecl::Format;
49 using ecl::Hex;
50 using ecl::NoAlign;
51 using ecl::Thread;
52 using ecl::MilliSleep;
53 using ecl::TimeStamp;
54 
55 /*****************************************************************************
56 ** Classes
57 *****************************************************************************/
58 
59 class Reader {
60 public:
61  Reader(SocketServer &socket_server, bool timestamps_reqd, bool hex_format_reqd, const int &port_number) :
62  socket(socket_server),
63  timestamps(timestamps_reqd),
64  hex(hex_format_reqd),
65  port(port_number),
66  new_line(true)
67  {}
68 
69  void loop() {
70 
71  Format<unsigned char> hex_format(-1,NoAlign,Hex);
72  char c;
73  long ch_read;
74  MilliSleep sleep;
75 
76  if ( hex ) { std::cout << "Hex format" << std::endl; } else { std::cout << "Ascii format" << std::endl; }
77 
78  while (1) {
79  ch_read = socket.read(c);
80  if ( ch_read > 0 ) {
81  if ( hex ) {
82  if ( timestamps ) {
83  if ( new_line ) { timestamp.stamp(); }
84  std::cout << "[" << timestamp << "] : ";
85  }
86  std::cout << hex_format(c) << std::endl;
87  } else {
88  if ( timestamps && new_line ) {
89  timestamp.stamp();
90  std::cout << "[" << timestamp << "] : ";
91  }
92  std::cout << c;
93  }
94  std::cout.flush();
95  if ( timestamps ) {
96  if ( new_line ) {
97  new_line = false;
98  } else if ( c == '\n' ) {
99  new_line = true;
100  }
101  }
102  } else if ( ch_read < 0 ) {
103  if ( ch_read == ConnectionHungUp ) {
104  std::cout << "Client Hung Up." << std::endl;
105  exit(EXIT_FAILURE);
106  }
107  } else {
108  // nothing read
109  }
110  sleep(15);
111  }
112 
113  }
114 
115 private:
116  SocketServer &socket;
117  TimeStamp timestamp;
118  bool timestamps;
119  bool hex;
120  int port;
121  bool new_line;
122 };
123 
124 class Writer {
125 public:
126  Writer(SocketServer &socket_server, bool timestamps_reqd) :
127  socket(socket_server),
128  timestamps(timestamps_reqd)
129  {}
130 
131  void loop() {
132  MilliSleep sleep;
133  char buffer[256];
134  memset(buffer,0,256);
135  char *s_ptr;
136  while( 1 ) {
137  if ( fgets(buffer,80,stdin) == NULL ) {
138  break;
139  }
140  // fgets always terminates with a null character, even if it manages
141  // to read n-1 chars
142  s_ptr = buffer;
143  while ( *s_ptr != '\0') { ++s_ptr; }
144  if ( timestamps ) { timestamp.stamp(); }
145  socket.write(buffer,s_ptr - buffer);
146  if ( timestamps ) {
147  std::cout << "[" << timestamp << "] : ";
148  }
149  std::cout << buffer; // already terminated by an endl;
150  std::cout.flush();
151  sleep(500);
152  }
153 
154  }
155 
156 private:
157  SocketServer &socket;
158  TimeStamp timestamp;
159  bool timestamps;
160 };
161 
162 } // namespace demos
163 } // namespace ecl
164 
165 /*****************************************************************************
166 ** Using
167 *****************************************************************************/
168 
169 using namespace ecl::demos;
170 
171 /*****************************************************************************
172 ** Main
173 *****************************************************************************/
174 
175 int main(int argc, char** argv) {
176 
177  std::cout << std::endl;
178  std::cout << "***********************************************************" << std::endl;
179  std::cout << " Parsing Command Line" << std::endl;
180  std::cout << "***********************************************************" << std::endl;
181  std::cout << std::endl;
182  int port = 0;
183  bool hex(false);
184  bool timestamps(false);
185 
186  try {
187  CmdLine cmd("This is a simple interface for making serving from a socket.",' ',"0.1");
188  ValueArg<int> arg_port("p","port","Port to connect to [1470].",false,1470,"integer");
189  SwitchArg switch_hex("x","hex","Enable hex output.",false);
190  SwitchArg switch_timestamps("t","timestamp","Timestamp incoming/outgoings.",false);
191 
192  cmd.add(arg_port);
193  cmd.add(switch_hex);
194  cmd.add(switch_timestamps);
195  cmd.parse(argc,argv);
196 
197  hex = switch_hex.getValue();
198  port = arg_port.getValue();
199  timestamps = switch_timestamps.getValue();
200 
201  } catch ( ArgException &e ) {
202  std::cerr << "error: " << e.error() << " for arg " << e.argId() << std::endl;
203  }
204 
205  std::cout << "Listening on port: " << port << std::endl;
206 
207  std::cout << std::endl;
208  std::cout << "***********************************************************" << std::endl;
209  std::cout << " Read and Write Threads " << std::endl;
210  std::cout << "***********************************************************" << std::endl;
211  std::cout << std::endl;
212 
213  SocketServer server(port);
214  server.listen();
215  Writer writer(server,timestamps);
216  Reader reader(server,timestamps,hex,port);
217  Thread read_thread(&Reader::loop, reader);
218  Thread write_thread(&Writer::loop, writer);
219 
220  read_thread.join();
221  write_thread.join();
222 
223  std::cout << std::endl;
224  std::cout << "***********************************************************" << std::endl;
225  std::cout << " Passed" << std::endl;
226  std::cout << "***********************************************************" << std::endl;
227  std::cout << std::endl;
228 
229  return 0;
230 }
231 
232 #endif /* ECL_IS_POSIX */
233 #endif /* !ECL_IS_MAC */
234 
235 #if !defined ECL_IS_POSIX || ECL_IS_MAC
236 
237 #include <iostream>
238 
239 int main(int argc, char **argv) {
240 
241  std::cout << "This is a posix (not mac) only app." << std::endl;
242  return 0;
243 }
244 
245 #endif
main
int main(int argc, char **argv)
Definition: socket_server.cpp:239
ecl::Hex
Hex
ecl::ConnectionHungUp
ConnectionHungUp
ecl::NoAlign
NoAlign
command_line.hpp
formatters.hpp
ecl::CmdLine
socket_connection_status.hpp
sleep.hpp
thread.hpp
ecl::ArgException
ecl::SwitchArg
ecl::Format
ecl::ValueArg
socket.hpp
ecl::demos
Demo programs.
ecl
timestamp.hpp


ecl_core_apps
Author(s): Daniel Stonier
autogenerated on Wed Mar 2 2022 00:16:52