Visual Servoing Platform  version 3.3.1 under development (2020-08-12)
vpNetwork.h
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2019 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See http://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * TCP Network
33  *
34  * Authors:
35  * Aurelien Yol
36  *
37  *****************************************************************************/
38 
39 #ifndef vpNetwork_H
40 #define vpNetwork_H
41 
42 #include <visp3/core/vpConfig.h>
43 #include <visp3/core/vpRequest.h>
44 
45 #include <iostream>
46 #include <stdio.h>
47 #include <string.h>
48 #include <vector>
49 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
50 #include <sys/select.h>
51 #endif
52 
53 // inet_ntop() not supported on win XP
54 #ifdef VISP_HAVE_FUNC_INET_NTOP
55 
56 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
57 # include <arpa/inet.h>
58 # include <netdb.h>
59 # include <netinet/in.h>
60 # include <sys/socket.h>
61 # include <unistd.h>
62 #else
63 # include <io.h>
64 //# include<winsock.h>
65 # include <winsock2.h>
66 //# pragma comment(lib, "ws2_32.lib") // Done by CMake in main CMakeLists.txt
67 #endif
68 
69 #if defined(__APPLE__) && defined(__MACH__) // Apple OSX and iOS (Darwin)
70 # include <TargetConditionals.h> // To detect OSX or IOS using TARGET_OS_IPHONE or TARGET_OS_IOS macro
71 #endif
72 
90 class VISP_EXPORT vpNetwork
91 {
92 protected:
93 #ifndef DOXYGEN_SHOULD_SKIP_THIS
94  struct vpReceptor {
95 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
96  int socketFileDescriptorReceptor;
97  socklen_t receptorAddressSize;
98 #else
99  SOCKET socketFileDescriptorReceptor;
100  int receptorAddressSize;
101 #endif
102  struct sockaddr_in receptorAddress;
103  std::string receptorIP;
104 
105  vpReceptor() : socketFileDescriptorReceptor(0), receptorAddressSize(), receptorAddress(), receptorIP() {}
106  };
107 
108  struct vpEmitter {
109  struct sockaddr_in emitterAddress;
110 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
111  int socketFileDescriptorEmitter;
112 #else
113  SOCKET socketFileDescriptorEmitter;
114 #endif
115  vpEmitter() : emitterAddress(), socketFileDescriptorEmitter(0)
116  {
117  emitterAddress.sin_family = AF_INET;
118  emitterAddress.sin_addr.s_addr = INADDR_ANY;
119  emitterAddress.sin_port = 0;
120  socketFileDescriptorEmitter = 0;
121  }
122  };
123 #endif
124 
125  //######## PARAMETERS ########
126  //# #
127  //############################
128 
129  vpEmitter emitter;
130  std::vector<vpReceptor> receptor_list;
132 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
134 #else
135  SOCKET socketMax;
136 #endif
137 
138  // Message Handling
139  std::vector<vpRequest *> request_list;
140 
141  unsigned int max_size_message;
142  std::string separator;
143  std::string beginning;
144  std::string end;
145  std::string param_sep;
146 
148 
149  struct timeval tv;
150  long tv_sec;
151  long tv_usec;
152 
154 
155 private:
156  std::vector<int> _handleRequests();
157  int _handleFirstRequest();
158 
159  void _receiveRequest();
160  void _receiveRequestFrom(const unsigned int &receptorEmitting);
161  int _receiveRequestOnce();
162  int _receiveRequestOnceFrom(const unsigned int &receptorEmitting);
163 
164 public:
165  vpNetwork();
166  virtual ~vpNetwork();
167 
168  void addDecodingRequest(vpRequest *);
169 
170  int getReceptorIndex(const char *name);
171 
179  std::string getRequestIdFromIndex(const int &ind)
180  {
181  if (ind >= (int)request_list.size() || ind < 0)
182  return "";
183  return request_list[(unsigned)ind]->getId();
184  }
185 
193  unsigned int getMaxSizeReceivedMessage() { return max_size_message; }
194 
195  void print(const char *id = "");
196 
197  template <typename T> int receive(T *object, const unsigned int &sizeOfObject = sizeof(T));
198  template <typename T>
199  int receiveFrom(T *object, const unsigned int &receptorEmitting, const unsigned int &sizeOfObject = sizeof(T));
200 
201  std::vector<int> receiveRequest();
202  std::vector<int> receiveRequestFrom(const unsigned int &receptorEmitting);
203  int receiveRequestOnce();
204  int receiveRequestOnceFrom(const unsigned int &receptorEmitting);
205 
206  std::vector<int> receiveAndDecodeRequest();
207  std::vector<int> receiveAndDecodeRequestFrom(const unsigned int &receptorEmitting);
208  int receiveAndDecodeRequestOnce();
209  int receiveAndDecodeRequestOnceFrom(const unsigned int &receptorEmitting);
210 
211  void removeDecodingRequest(const char *);
212 
213  template <typename T> int send(T *object, const int unsigned &sizeOfObject = sizeof(T));
214  template <typename T> int sendTo(T *object, const unsigned int &dest, const unsigned int &sizeOfObject = sizeof(T));
215 
216  int sendRequest(vpRequest &req);
217  int sendRequestTo(vpRequest &req, const unsigned int &dest);
218 
219  int sendAndEncodeRequest(vpRequest &req);
220  int sendAndEncodeRequestTo(vpRequest &req, const unsigned int &dest);
221 
229  void setMaxSizeReceivedMessage(const unsigned int &s) { max_size_message = s; }
230 
239  void setTimeoutSec(const long &sec) { tv_sec = sec; }
240 
249  void setTimeoutUSec(const long &usec) { tv_usec = usec; }
250 
256  void setVerbose(const bool &mode) { verboseMode = mode; }
257 };
258 
259 //######## Definition of Template Functions ########
260 //# #
261 //##################################################
262 
283 template <typename T> int vpNetwork::receive(T *object, const unsigned int &sizeOfObject)
284 {
285  if (receptor_list.size() == 0) {
286  if (verboseMode)
287  vpTRACE("No receptor");
288  return -1;
289  }
290 
291  tv.tv_sec = tv_sec;
292 #if TARGET_OS_IPHONE
293  tv.tv_usec = (int)tv_usec;
294 #else
295  tv.tv_usec = tv_usec;
296 #endif
297 
298  FD_ZERO(&readFileDescriptor);
299 
300  for (unsigned int i = 0; i < receptor_list.size(); i++) {
301  FD_SET((unsigned int)receptor_list[i].socketFileDescriptorReceptor, &readFileDescriptor);
302 
303  if (i == 0)
304  socketMax = receptor_list[i].socketFileDescriptorReceptor;
305 
306  if (socketMax < receptor_list[i].socketFileDescriptorReceptor)
307  socketMax = receptor_list[i].socketFileDescriptorReceptor;
308  }
309 
310  int value = select((int)socketMax + 1, &readFileDescriptor, NULL, NULL, &tv);
311  int numbytes = 0;
312 
313  if (value == -1) {
314  if (verboseMode)
315  vpERROR_TRACE("Select error");
316  return -1;
317  } else if (value == 0) {
318  // Timeout
319  return 0;
320  } else {
321  for (unsigned int i = 0; i < receptor_list.size(); i++) {
322  if (FD_ISSET((unsigned int)receptor_list[i].socketFileDescriptorReceptor, &readFileDescriptor)) {
323 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
324  numbytes = recv(receptor_list[i].socketFileDescriptorReceptor, (char *)(void *)object, sizeOfObject, 0);
325 #else
326  numbytes = recv((unsigned int)receptor_list[i].socketFileDescriptorReceptor, (char *)(void *)object,
327  (int)sizeOfObject, 0);
328 #endif
329  if (numbytes <= 0) {
330  std::cout << "Disconnected : " << inet_ntoa(receptor_list[i].receptorAddress.sin_addr) << std::endl;
331  receptor_list.erase(receptor_list.begin() + (int)i);
332  return numbytes;
333  }
334 
335  break;
336  }
337  }
338  }
339 
340  return numbytes;
341 }
342 
364 template <typename T>
365 int vpNetwork::receiveFrom(T *object, const unsigned int &receptorEmitting, const unsigned int &sizeOfObject)
366 {
367  if (receptor_list.size() == 0 || receptorEmitting > (unsigned int)receptor_list.size() - 1) {
368  if (verboseMode)
369  vpTRACE("No receptor at the specified index");
370  return -1;
371  }
372 
373  tv.tv_sec = tv_sec;
374 #if TARGET_OS_IPHONE
375  tv.tv_usec = (int)tv_usec;
376 #else
377  tv.tv_usec = tv_usec;
378 #endif
379 
380  FD_ZERO(&readFileDescriptor);
381 
382  socketMax = receptor_list[receptorEmitting].socketFileDescriptorReceptor;
383  FD_SET((unsigned int)receptor_list[receptorEmitting].socketFileDescriptorReceptor, &readFileDescriptor);
384 
385  int value = select((int)socketMax + 1, &readFileDescriptor, NULL, NULL, &tv);
386  int numbytes = 0;
387 
388  if (value == -1) {
389  if (verboseMode)
390  vpERROR_TRACE("Select error");
391  return -1;
392  } else if (value == 0) {
393  // timeout
394  return 0;
395  } else {
396  if (FD_ISSET((unsigned int)receptor_list[receptorEmitting].socketFileDescriptorReceptor, &readFileDescriptor)) {
397 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
398  numbytes =
399  recv(receptor_list[receptorEmitting].socketFileDescriptorReceptor, (char *)(void *)object, sizeOfObject, 0);
400 #else
401  numbytes = recv((unsigned int)receptor_list[receptorEmitting].socketFileDescriptorReceptor,
402  (char *)(void *)object, (int)sizeOfObject, 0);
403 #endif
404  if (numbytes <= 0) {
405  std::cout << "Disconnected : " << inet_ntoa(receptor_list[receptorEmitting].receptorAddress.sin_addr)
406  << std::endl;
407  receptor_list.erase(receptor_list.begin() + (int)receptorEmitting);
408  return numbytes;
409  }
410  }
411  }
412 
413  return numbytes;
414 }
415 
437 template <typename T> int vpNetwork::send(T *object, const unsigned int &sizeOfObject)
438 {
439  if (receptor_list.size() == 0) {
440  if (verboseMode)
441  vpTRACE("No receptor !");
442  return 0;
443  }
444 
445  int flags = 0;
446 //#if ! defined(APPLE) && ! defined(SOLARIS) && ! defined(_WIN32)
447 #if defined(__linux__)
448  flags = MSG_NOSIGNAL; // Only for Linux
449 #endif
450 
451 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
452  return sendto(receptor_list[0].socketFileDescriptorReceptor, (const char *)(void *)object, sizeOfObject, flags,
453  (sockaddr *)&receptor_list[0].receptorAddress, receptor_list[0].receptorAddressSize);
454 #else
455  return sendto(receptor_list[0].socketFileDescriptorReceptor, (const char *)(void *)object, (int)sizeOfObject, flags,
456  (sockaddr *)&receptor_list[0].receptorAddress, receptor_list[0].receptorAddressSize);
457 #endif
458 }
459 
481 template <typename T> int vpNetwork::sendTo(T *object, const unsigned int &dest, const unsigned int &sizeOfObject)
482 {
483  if (receptor_list.size() == 0 || dest > (unsigned int)receptor_list.size() - 1) {
484  if (verboseMode)
485  vpTRACE("No receptor at the specified index.");
486  return 0;
487  }
488 
489  int flags = 0;
490 //#if ! defined(APPLE) && ! defined(SOLARIS) && ! defined(_WIN32)
491 #if defined(__linux__)
492  flags = MSG_NOSIGNAL; // Only for Linux
493 #endif
494 
495 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
496  return sendto(receptor_list[dest].socketFileDescriptorReceptor, (const char *)(void *)object, sizeOfObject, flags,
497  (sockaddr *)&receptor_list[dest].receptorAddress, receptor_list[dest].receptorAddressSize);
498 #else
499  return sendto(receptor_list[dest].socketFileDescriptorReceptor, (const char *)(void *)object, (int)sizeOfObject,
500  flags, (sockaddr *)&receptor_list[dest].receptorAddress, receptor_list[dest].receptorAddressSize);
501 #endif
502 }
503 
504 #endif
505 #endif
unsigned int max_size_message
Definition: vpNetwork.h:141
std::string separator
Definition: vpNetwork.h:142
void setMaxSizeReceivedMessage(const unsigned int &s)
Definition: vpNetwork.h:229
std::string beginning
Definition: vpNetwork.h:143
This the request that will transit on the network.
Definition: vpRequest.h:131
std::string getRequestIdFromIndex(const int &ind)
Definition: vpNetwork.h:179
fd_set readFileDescriptor
Definition: vpNetwork.h:131
#define vpERROR_TRACE
Definition: vpDebug.h:393
This class represents a Transmission Control Protocol (TCP) network.
Definition: vpNetwork.h:90
int send(T *object, const int unsigned &sizeOfObject=sizeof(T))
int socketMax
Definition: vpNetwork.h:133
unsigned int getMaxSizeReceivedMessage()
Definition: vpNetwork.h:193
std::string end
Definition: vpNetwork.h:144
#define vpTRACE
Definition: vpDebug.h:416
vpEmitter emitter
Definition: vpNetwork.h:129
int receive(T *object, const unsigned int &sizeOfObject=sizeof(T))
Definition: vpNetwork.h:283
void setTimeoutUSec(const long &usec)
Definition: vpNetwork.h:249
long tv_sec
Definition: vpNetwork.h:150
bool verboseMode
Definition: vpNetwork.h:153
std::vector< vpReceptor > receptor_list
Definition: vpNetwork.h:130
long tv_usec
Definition: vpNetwork.h:151
void setVerbose(const bool &mode)
Definition: vpNetwork.h:256
void setTimeoutSec(const long &sec)
Definition: vpNetwork.h:239
std::string currentMessageReceived
Definition: vpNetwork.h:147
int sendTo(T *object, const unsigned int &dest, const unsigned int &sizeOfObject=sizeof(T))
Definition: vpNetwork.h:481
std::string param_sep
Definition: vpNetwork.h:145
std::vector< vpRequest * > request_list
Definition: vpNetwork.h:139
int receiveFrom(T *object, const unsigned int &receptorEmitting, const unsigned int &sizeOfObject=sizeof(T))
Definition: vpNetwork.h:365