Visual Servoing Platform  version 3.0.1
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
vpNetwork.h
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2017 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * ("GPL") version 2 as published by the Free Software Foundation.
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 http://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  * Authors:
34  * Aurelien Yol
35  *
36  *****************************************************************************/
37 
38 #ifndef vpNetwork_H
39 #define vpNetwork_H
40 
41 #include <visp3/core/vpConfig.h>
42 #include <visp3/core/vpRequest.h>
43 
44 #include <vector>
45 #include <stdio.h>
46 #include <string.h>
47 #include <iostream>
48 
49 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
50 # include <unistd.h>
51 # include <sys/socket.h>
52 # include <netinet/in.h>
53 # include <arpa/inet.h>
54 # include <netdb.h>
55 #else
56 # include<io.h>
57 //# include<winsock.h>
58 # include<winsock2.h>
59 //# pragma comment(lib, "ws2_32.lib") // Done by CMake in main CMakeLists.txt
60 #endif
61 
62 #if defined(__APPLE__) && defined(__MACH__) // Apple OSX and iOS (Darwin)
63 # include <TargetConditionals.h> // To detect OSX or IOS using TARGET_OS_IPHONE or TARGET_OS_IOS macro
64 #endif
65 
82 class VISP_EXPORT vpNetwork
83 {
84 protected:
85 #ifndef DOXYGEN_SHOULD_SKIP_THIS
86  struct vpReceptor{
87 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
88  int socketFileDescriptorReceptor;
89  socklen_t receptorAddressSize;
90 #else
91  SOCKET socketFileDescriptorReceptor;
92  int receptorAddressSize;
93 #endif
94  struct sockaddr_in receptorAddress;
95  std::string receptorIP;
96 
97  vpReceptor() : socketFileDescriptorReceptor(0), receptorAddressSize(), receptorAddress(), receptorIP() {}
98  };
99 
100  struct vpEmitter{
101  struct sockaddr_in emitterAddress;
102 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
103  int socketFileDescriptorEmitter;
104 #else
105  SOCKET socketFileDescriptorEmitter;
106 #endif
107  vpEmitter() : emitterAddress(), socketFileDescriptorEmitter(0)
108  {
109  emitterAddress.sin_family = AF_INET;
110  emitterAddress.sin_addr.s_addr = INADDR_ANY;
111  emitterAddress.sin_port = 0;
112  socketFileDescriptorEmitter = 0;
113  }
114  };
115 #endif
116 
117  //######## PARAMETERS ########
118  //# #
119  //############################
120 
121  vpEmitter emitter;
122  std::vector<vpReceptor> receptor_list;
124 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
126 #else
127  SOCKET socketMax;
128 #endif
129 
130  //Message Handling
131  std::vector<vpRequest*> request_list;
132 
133  unsigned int max_size_message;
134  std::string separator;
135  std::string beginning;
136  std::string end;
137  std::string param_sep;
138 
140 
141  struct timeval tv;
142  long tv_sec;
143  long tv_usec;
144 
146 
147 private:
148 
149  std::vector<int> _handleRequests();
150  int _handleFirstRequest();
151 
152  void _receiveRequest();
153  void _receiveRequestFrom(const unsigned int &receptorEmitting);
154  int _receiveRequestOnce();
155  int _receiveRequestOnceFrom(const unsigned int &receptorEmitting);
156 
157 public:
158 
159  vpNetwork();
160  virtual ~vpNetwork();
161 
162  void addDecodingRequest(vpRequest *);
163 
164  int getReceptorIndex(const char *name);
165 
173  std::string getRequestIdFromIndex(const int &ind){
174  if(ind >= (int)request_list.size() || ind < 0)
175  return "";
176  return request_list[(unsigned)ind]->getId();
177  }
178 
186  unsigned int getMaxSizeReceivedMessage(){ return max_size_message; }
187 
188  void print(const char *id = "");
189 
190  template<typename T>
191  int receive(T* object, const unsigned int &sizeOfObject = sizeof(T));
192  template<typename T>
193  int receiveFrom(T* object, const unsigned int &receptorEmitting, const unsigned int &sizeOfObject = sizeof(T));
194 
195  std::vector<int> receiveRequest();
196  std::vector<int> receiveRequestFrom(const unsigned int &receptorEmitting);
197  int receiveRequestOnce();
198  int receiveRequestOnceFrom(const unsigned int &receptorEmitting);
199 
200  std::vector<int> receiveAndDecodeRequest();
201  std::vector<int> receiveAndDecodeRequestFrom(const unsigned int &receptorEmitting);
202  int receiveAndDecodeRequestOnce();
203  int receiveAndDecodeRequestOnceFrom(const unsigned int &receptorEmitting);
204 
205  void removeDecodingRequest(const char *);
206 
207  template<typename T>
208  int send(T* object, const int unsigned &sizeOfObject = sizeof(T));
209  template<typename T>
210  int sendTo(T* object, const unsigned int &dest, const unsigned int &sizeOfObject = sizeof(T));
211 
212  int sendRequest(vpRequest &req);
213  int sendRequestTo(vpRequest &req, const unsigned int &dest);
214 
215  int sendAndEncodeRequest(vpRequest &req);
216  int sendAndEncodeRequestTo(vpRequest &req, const unsigned int &dest);
217 
225  void setMaxSizeReceivedMessage(const unsigned int &s){ max_size_message = s;}
226 
235  void setTimeoutSec(const long &sec){ tv_sec = sec; }
236 
245  void setTimeoutUSec(const long &usec){ tv_usec = usec; }
246 
252  void setVerbose(const bool &mode){ verboseMode = mode; }
253 };
254 
255 //######## Definition of Template Functions ########
256 //# #
257 //##################################################
258 
278 template<typename T>
279 int vpNetwork::receive(T* object, const unsigned int &sizeOfObject)
280 {
281  if(receptor_list.size() == 0)
282  {
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) socketMax = receptor_list[i].socketFileDescriptorReceptor;
304  }
305 
306  int value = select((int)socketMax+1,&readFileDescriptor,NULL,NULL,&tv);
307  int numbytes = 0;
308 
309  if(value == -1){
310  if(verboseMode)
311  vpERROR_TRACE( "Select error" );
312  return -1;
313  }
314  else if(value == 0){
315  //Timeout
316  return 0;
317  }
318  else{
319  for(unsigned int i=0; i<receptor_list.size(); i++){
320  if(FD_ISSET((unsigned int)receptor_list[i].socketFileDescriptorReceptor,&readFileDescriptor)){
321 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
322  numbytes = recv(receptor_list[i].socketFileDescriptorReceptor, (char*)(void*)object, sizeOfObject, 0);
323 #else
324  numbytes = recv((unsigned int)receptor_list[i].socketFileDescriptorReceptor, (char*)(void*)object, (int)sizeOfObject, 0);
325 #endif
326  if(numbytes <= 0)
327  {
328  std::cout << "Disconnected : " << inet_ntoa(receptor_list[i].receptorAddress.sin_addr) << std::endl;
329  receptor_list.erase(receptor_list.begin()+(int)i);
330  return numbytes;
331  }
332 
333  break;
334  }
335  }
336  }
337 
338  return numbytes;
339 }
340 
362 template<typename T>
363 int vpNetwork::receiveFrom(T* object, const unsigned int &receptorEmitting, const unsigned int &sizeOfObject)
364 {
365  if(receptor_list.size() == 0 || receptorEmitting > (unsigned int)receptor_list.size()-1 )
366  {
367  if(verboseMode)
368  vpTRACE( "No receptor at the specified index" );
369  return -1;
370  }
371 
372  tv.tv_sec = tv_sec;
373 #if TARGET_OS_IPHONE
374  tv.tv_usec = (int)tv_usec;
375 #else
376  tv.tv_usec = tv_usec;
377 #endif
378 
379  FD_ZERO(&readFileDescriptor);
380 
381  socketMax = receptor_list[receptorEmitting].socketFileDescriptorReceptor;
382  FD_SET((unsigned int)receptor_list[receptorEmitting].socketFileDescriptorReceptor,&readFileDescriptor);
383 
384  int value = select((int)socketMax+1,&readFileDescriptor,NULL,NULL,&tv);
385  int numbytes = 0;
386 
387  if(value == -1){
388  if(verboseMode)
389  vpERROR_TRACE( "Select error" );
390  return -1;
391  }
392  else if(value == 0){
393  //timeout
394  return 0;
395  }
396  else{
397  if(FD_ISSET((unsigned int)receptor_list[receptorEmitting].socketFileDescriptorReceptor,&readFileDescriptor)){
398 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
399  numbytes = recv(receptor_list[receptorEmitting].socketFileDescriptorReceptor, (char*)(void*)object, sizeOfObject, 0);
400 #else
401  numbytes = recv((unsigned int)receptor_list[receptorEmitting].socketFileDescriptorReceptor, (char*)(void*)object, (int)sizeOfObject, 0);
402 #endif
403  if(numbytes <= 0)
404  {
405  std::cout << "Disconnected : " << inet_ntoa(receptor_list[receptorEmitting].receptorAddress.sin_addr) << std::endl;
406  receptor_list.erase(receptor_list.begin()+(int)receptorEmitting);
407  return numbytes;
408  }
409  }
410  }
411 
412  return numbytes;
413 }
414 
435 template<typename T>
436 int vpNetwork::send(T* object, const unsigned int &sizeOfObject)
437 {
438  if(receptor_list.size() == 0)
439  {
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,
453  flags, (sockaddr*) &receptor_list[0].receptorAddress,receptor_list[0].receptorAddressSize);
454 #else
455  return sendto(receptor_list[0].socketFileDescriptorReceptor, (const char*)(void*)object, (int)sizeOfObject,
456  flags, (sockaddr*) &receptor_list[0].receptorAddress,receptor_list[0].receptorAddressSize);
457 #endif
458 
459 }
460 
482 template<typename T>
483 int vpNetwork::sendTo(T* object, const unsigned int &dest, const unsigned int &sizeOfObject)
484 {
485  if(receptor_list.size() == 0 || dest > (unsigned int)receptor_list.size()-1 )
486  {
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,
500  flags, (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 
507 #endif
unsigned int max_size_message
Definition: vpNetwork.h:133
std::string separator
Definition: vpNetwork.h:134
void setMaxSizeReceivedMessage(const unsigned int &s)
Definition: vpNetwork.h:225
std::string beginning
Definition: vpNetwork.h:135
This the request that will transit on the network.
Definition: vpRequest.h:130
std::vector< vpRequest * > request_list
Definition: vpNetwork.h:131
std::string getRequestIdFromIndex(const int &ind)
Definition: vpNetwork.h:173
fd_set readFileDescriptor
Definition: vpNetwork.h:123
#define vpERROR_TRACE
Definition: vpDebug.h:391
This class represents a Transmission Control Protocol (TCP) network.
Definition: vpNetwork.h:82
int send(T *object, const int unsigned &sizeOfObject=sizeof(T))
int socketMax
Definition: vpNetwork.h:125
unsigned int getMaxSizeReceivedMessage()
Definition: vpNetwork.h:186
std::string end
Definition: vpNetwork.h:136
#define vpTRACE
Definition: vpDebug.h:414
vpEmitter emitter
Definition: vpNetwork.h:121
int receive(T *object, const unsigned int &sizeOfObject=sizeof(T))
Definition: vpNetwork.h:279
void setTimeoutUSec(const long &usec)
Definition: vpNetwork.h:245
long tv_sec
Definition: vpNetwork.h:142
bool verboseMode
Definition: vpNetwork.h:145
struct timeval tv
Definition: vpNetwork.h:141
std::vector< vpReceptor > receptor_list
Definition: vpNetwork.h:122
long tv_usec
Definition: vpNetwork.h:143
void setVerbose(const bool &mode)
Definition: vpNetwork.h:252
void setTimeoutSec(const long &sec)
Definition: vpNetwork.h:235
std::string currentMessageReceived
Definition: vpNetwork.h:139
int sendTo(T *object, const unsigned int &dest, const unsigned int &sizeOfObject=sizeof(T))
Definition: vpNetwork.h:483
std::string param_sep
Definition: vpNetwork.h:137
int receiveFrom(T *object, const unsigned int &receptorEmitting, const unsigned int &sizeOfObject=sizeof(T))
Definition: vpNetwork.h:363