Visual Servoing Platform  version 3.2.0 under development (2019-01-22)
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 
50 // inet_ntop() not supported on win XP
51 #ifdef VISP_HAVE_FUNC_INET_NTOP
52 
53 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
54 # include <arpa/inet.h>
55 # include <netdb.h>
56 # include <netinet/in.h>
57 # include <sys/socket.h>
58 # include <unistd.h>
59 #else
60 # include <io.h>
61 //# include<winsock.h>
62 # include <winsock2.h>
63 //# pragma comment(lib, "ws2_32.lib") // Done by CMake in main CMakeLists.txt
64 #endif
65 
66 #if defined(__APPLE__) && defined(__MACH__) // Apple OSX and iOS (Darwin)
67 # include <TargetConditionals.h> // To detect OSX or IOS using TARGET_OS_IPHONE or TARGET_OS_IOS macro
68 #endif
69 
87 class VISP_EXPORT vpNetwork
88 {
89 protected:
90 #ifndef DOXYGEN_SHOULD_SKIP_THIS
91  struct vpReceptor {
92 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
93  int socketFileDescriptorReceptor;
94  socklen_t receptorAddressSize;
95 #else
96  SOCKET socketFileDescriptorReceptor;
97  int receptorAddressSize;
98 #endif
99  struct sockaddr_in receptorAddress;
100  std::string receptorIP;
101 
102  vpReceptor() : socketFileDescriptorReceptor(0), receptorAddressSize(), receptorAddress(), receptorIP() {}
103  };
104 
105  struct vpEmitter {
106  struct sockaddr_in emitterAddress;
107 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
108  int socketFileDescriptorEmitter;
109 #else
110  SOCKET socketFileDescriptorEmitter;
111 #endif
112  vpEmitter() : emitterAddress(), socketFileDescriptorEmitter(0)
113  {
114  emitterAddress.sin_family = AF_INET;
115  emitterAddress.sin_addr.s_addr = INADDR_ANY;
116  emitterAddress.sin_port = 0;
117  socketFileDescriptorEmitter = 0;
118  }
119  };
120 #endif
121 
122  //######## PARAMETERS ########
123  //# #
124  //############################
125 
126  vpEmitter emitter;
127  std::vector<vpReceptor> receptor_list;
129 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
131 #else
132  SOCKET socketMax;
133 #endif
134 
135  // Message Handling
136  std::vector<vpRequest *> request_list;
137 
138  unsigned int max_size_message;
139  std::string separator;
140  std::string beginning;
141  std::string end;
142  std::string param_sep;
143 
145 
146  struct timeval tv;
147  long tv_sec;
148  long tv_usec;
149 
151 
152 private:
153  std::vector<int> _handleRequests();
154  int _handleFirstRequest();
155 
156  void _receiveRequest();
157  void _receiveRequestFrom(const unsigned int &receptorEmitting);
158  int _receiveRequestOnce();
159  int _receiveRequestOnceFrom(const unsigned int &receptorEmitting);
160 
161 public:
162  vpNetwork();
163  virtual ~vpNetwork();
164 
165  void addDecodingRequest(vpRequest *);
166 
167  int getReceptorIndex(const char *name);
168 
176  std::string getRequestIdFromIndex(const int &ind)
177  {
178  if (ind >= (int)request_list.size() || ind < 0)
179  return "";
180  return request_list[(unsigned)ind]->getId();
181  }
182 
190  unsigned int getMaxSizeReceivedMessage() { return max_size_message; }
191 
192  void print(const char *id = "");
193 
194  template <typename T> int receive(T *object, const unsigned int &sizeOfObject = sizeof(T));
195  template <typename T>
196  int receiveFrom(T *object, const unsigned int &receptorEmitting, const unsigned int &sizeOfObject = sizeof(T));
197 
198  std::vector<int> receiveRequest();
199  std::vector<int> receiveRequestFrom(const unsigned int &receptorEmitting);
200  int receiveRequestOnce();
201  int receiveRequestOnceFrom(const unsigned int &receptorEmitting);
202 
203  std::vector<int> receiveAndDecodeRequest();
204  std::vector<int> receiveAndDecodeRequestFrom(const unsigned int &receptorEmitting);
205  int receiveAndDecodeRequestOnce();
206  int receiveAndDecodeRequestOnceFrom(const unsigned int &receptorEmitting);
207 
208  void removeDecodingRequest(const char *);
209 
210  template <typename T> int send(T *object, const int unsigned &sizeOfObject = sizeof(T));
211  template <typename T> int sendTo(T *object, const unsigned int &dest, const unsigned int &sizeOfObject = sizeof(T));
212 
213  int sendRequest(vpRequest &req);
214  int sendRequestTo(vpRequest &req, const unsigned int &dest);
215 
216  int sendAndEncodeRequest(vpRequest &req);
217  int sendAndEncodeRequestTo(vpRequest &req, const unsigned int &dest);
218 
226  void setMaxSizeReceivedMessage(const unsigned int &s) { max_size_message = s; }
227 
236  void setTimeoutSec(const long &sec) { tv_sec = sec; }
237 
246  void setTimeoutUSec(const long &usec) { tv_usec = usec; }
247 
253  void setVerbose(const bool &mode) { verboseMode = mode; }
254 };
255 
256 //######## Definition of Template Functions ########
257 //# #
258 //##################################################
259 
280 template <typename T> int vpNetwork::receive(T *object, const unsigned int &sizeOfObject)
281 {
282  if (receptor_list.size() == 0) {
283  if (verboseMode)
284  vpTRACE("No receptor");
285  return -1;
286  }
287 
288  tv.tv_sec = tv_sec;
289 #if TARGET_OS_IPHONE
290  tv.tv_usec = (int)tv_usec;
291 #else
292  tv.tv_usec = tv_usec;
293 #endif
294 
295  FD_ZERO(&readFileDescriptor);
296 
297  for (unsigned int i = 0; i < receptor_list.size(); i++) {
298  FD_SET((unsigned int)receptor_list[i].socketFileDescriptorReceptor, &readFileDescriptor);
299 
300  if (i == 0)
301  socketMax = receptor_list[i].socketFileDescriptorReceptor;
302 
303  if (socketMax < receptor_list[i].socketFileDescriptorReceptor)
304  socketMax = receptor_list[i].socketFileDescriptorReceptor;
305  }
306 
307  int value = select((int)socketMax + 1, &readFileDescriptor, NULL, NULL, &tv);
308  int numbytes = 0;
309 
310  if (value == -1) {
311  if (verboseMode)
312  vpERROR_TRACE("Select error");
313  return -1;
314  } else if (value == 0) {
315  // Timeout
316  return 0;
317  } else {
318  for (unsigned int i = 0; i < receptor_list.size(); i++) {
319  if (FD_ISSET((unsigned int)receptor_list[i].socketFileDescriptorReceptor, &readFileDescriptor)) {
320 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
321  numbytes = recv(receptor_list[i].socketFileDescriptorReceptor, (char *)(void *)object, sizeOfObject, 0);
322 #else
323  numbytes = recv((unsigned int)receptor_list[i].socketFileDescriptorReceptor, (char *)(void *)object,
324  (int)sizeOfObject, 0);
325 #endif
326  if (numbytes <= 0) {
327  std::cout << "Disconnected : " << inet_ntoa(receptor_list[i].receptorAddress.sin_addr) << std::endl;
328  receptor_list.erase(receptor_list.begin() + (int)i);
329  return numbytes;
330  }
331 
332  break;
333  }
334  }
335  }
336 
337  return numbytes;
338 }
339 
361 template <typename T>
362 int vpNetwork::receiveFrom(T *object, const unsigned int &receptorEmitting, const unsigned int &sizeOfObject)
363 {
364  if (receptor_list.size() == 0 || receptorEmitting > (unsigned int)receptor_list.size() - 1) {
365  if (verboseMode)
366  vpTRACE("No receptor at the specified index");
367  return -1;
368  }
369 
370  tv.tv_sec = tv_sec;
371 #if TARGET_OS_IPHONE
372  tv.tv_usec = (int)tv_usec;
373 #else
374  tv.tv_usec = tv_usec;
375 #endif
376 
377  FD_ZERO(&readFileDescriptor);
378 
379  socketMax = receptor_list[receptorEmitting].socketFileDescriptorReceptor;
380  FD_SET((unsigned int)receptor_list[receptorEmitting].socketFileDescriptorReceptor, &readFileDescriptor);
381 
382  int value = select((int)socketMax + 1, &readFileDescriptor, NULL, NULL, &tv);
383  int numbytes = 0;
384 
385  if (value == -1) {
386  if (verboseMode)
387  vpERROR_TRACE("Select error");
388  return -1;
389  } else if (value == 0) {
390  // timeout
391  return 0;
392  } else {
393  if (FD_ISSET((unsigned int)receptor_list[receptorEmitting].socketFileDescriptorReceptor, &readFileDescriptor)) {
394 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
395  numbytes =
396  recv(receptor_list[receptorEmitting].socketFileDescriptorReceptor, (char *)(void *)object, sizeOfObject, 0);
397 #else
398  numbytes = recv((unsigned int)receptor_list[receptorEmitting].socketFileDescriptorReceptor,
399  (char *)(void *)object, (int)sizeOfObject, 0);
400 #endif
401  if (numbytes <= 0) {
402  std::cout << "Disconnected : " << inet_ntoa(receptor_list[receptorEmitting].receptorAddress.sin_addr)
403  << std::endl;
404  receptor_list.erase(receptor_list.begin() + (int)receptorEmitting);
405  return numbytes;
406  }
407  }
408  }
409 
410  return numbytes;
411 }
412 
434 template <typename T> int vpNetwork::send(T *object, const unsigned int &sizeOfObject)
435 {
436  if (receptor_list.size() == 0) {
437  if (verboseMode)
438  vpTRACE("No receptor !");
439  return 0;
440  }
441 
442  int flags = 0;
443 //#if ! defined(APPLE) && ! defined(SOLARIS) && ! defined(_WIN32)
444 #if defined(__linux__)
445  flags = MSG_NOSIGNAL; // Only for Linux
446 #endif
447 
448 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
449  return sendto(receptor_list[0].socketFileDescriptorReceptor, (const char *)(void *)object, sizeOfObject, flags,
450  (sockaddr *)&receptor_list[0].receptorAddress, receptor_list[0].receptorAddressSize);
451 #else
452  return sendto(receptor_list[0].socketFileDescriptorReceptor, (const char *)(void *)object, (int)sizeOfObject, flags,
453  (sockaddr *)&receptor_list[0].receptorAddress, receptor_list[0].receptorAddressSize);
454 #endif
455 }
456 
478 template <typename T> int vpNetwork::sendTo(T *object, const unsigned int &dest, const unsigned int &sizeOfObject)
479 {
480  if (receptor_list.size() == 0 || dest > (unsigned int)receptor_list.size() - 1) {
481  if (verboseMode)
482  vpTRACE("No receptor at the specified index.");
483  return 0;
484  }
485 
486  int flags = 0;
487 //#if ! defined(APPLE) && ! defined(SOLARIS) && ! defined(_WIN32)
488 #if defined(__linux__)
489  flags = MSG_NOSIGNAL; // Only for Linux
490 #endif
491 
492 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
493  return sendto(receptor_list[dest].socketFileDescriptorReceptor, (const char *)(void *)object, sizeOfObject, flags,
494  (sockaddr *)&receptor_list[dest].receptorAddress, receptor_list[dest].receptorAddressSize);
495 #else
496  return sendto(receptor_list[dest].socketFileDescriptorReceptor, (const char *)(void *)object, (int)sizeOfObject,
497  flags, (sockaddr *)&receptor_list[dest].receptorAddress, receptor_list[dest].receptorAddressSize);
498 #endif
499 }
500 
501 #endif
502 #endif
unsigned int max_size_message
Definition: vpNetwork.h:138
std::string separator
Definition: vpNetwork.h:139
void setMaxSizeReceivedMessage(const unsigned int &s)
Definition: vpNetwork.h:226
std::string beginning
Definition: vpNetwork.h:140
This the request that will transit on the network.
Definition: vpRequest.h:131
std::string getRequestIdFromIndex(const int &ind)
Definition: vpNetwork.h:176
fd_set readFileDescriptor
Definition: vpNetwork.h:128
#define vpERROR_TRACE
Definition: vpDebug.h:393
This class represents a Transmission Control Protocol (TCP) network.
Definition: vpNetwork.h:87
int send(T *object, const int unsigned &sizeOfObject=sizeof(T))
int socketMax
Definition: vpNetwork.h:130
unsigned int getMaxSizeReceivedMessage()
Definition: vpNetwork.h:190
std::string end
Definition: vpNetwork.h:141
#define vpTRACE
Definition: vpDebug.h:416
vpEmitter emitter
Definition: vpNetwork.h:126
int receive(T *object, const unsigned int &sizeOfObject=sizeof(T))
Definition: vpNetwork.h:280
void setTimeoutUSec(const long &usec)
Definition: vpNetwork.h:246
long tv_sec
Definition: vpNetwork.h:147
bool verboseMode
Definition: vpNetwork.h:150
std::vector< vpReceptor > receptor_list
Definition: vpNetwork.h:127
long tv_usec
Definition: vpNetwork.h:148
void setVerbose(const bool &mode)
Definition: vpNetwork.h:253
void setTimeoutSec(const long &sec)
Definition: vpNetwork.h:236
std::string currentMessageReceived
Definition: vpNetwork.h:144
int sendTo(T *object, const unsigned int &dest, const unsigned int &sizeOfObject=sizeof(T))
Definition: vpNetwork.h:478
std::string param_sep
Definition: vpNetwork.h:142
std::vector< vpRequest * > request_list
Definition: vpNetwork.h:136
int receiveFrom(T *object, const unsigned int &receptorEmitting, const unsigned int &sizeOfObject=sizeof(T))
Definition: vpNetwork.h:362