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