Visual Servoing Platform  version 3.0.0
vpNetwork.h
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2015 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 
79 class VISP_EXPORT vpNetwork
80 {
81 protected:
82 
83  struct vpReceptor{
84 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
87 #else
88  SOCKET socketFileDescriptorReceptor;
89  int receptorAddressSize;
90 #endif
91  struct sockaddr_in receptorAddress;
92  std::string receptorIP;
93 
94  vpReceptor() : socketFileDescriptorReceptor(0), receptorAddressSize(), receptorAddress(), receptorIP() {}
95  };
96 
97  struct vpEmitter{
98  struct sockaddr_in emitterAddress;
99 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
101 #else
102  SOCKET socketFileDescriptorEmitter;
103 #endif
104  vpEmitter() : emitterAddress(), socketFileDescriptorEmitter(0)
105  {
106  emitterAddress.sin_family = AF_INET;
107  emitterAddress.sin_addr.s_addr = INADDR_ANY;
108  emitterAddress.sin_port = 0;
109  socketFileDescriptorEmitter = 0;
110  }
111  };
112 
113  //######## PARAMETERS ########
114  //# #
115  //############################
116 
118  std::vector<vpReceptor> receptor_list;
120 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
122 #else
123  SOCKET socketMax;
124 #endif
125 
126  //Message Handling
127  std::vector<vpRequest*> request_list;
128 
129  unsigned int max_size_message;
130  std::string separator;
131  std::string beginning;
132  std::string end;
133  std::string param_sep;
134 
136 
137  struct timeval tv;
138  long tv_sec;
139  long tv_usec;
140 
142 
143 private:
144 
145  std::vector<int> _handleRequests();
146  int _handleFirstRequest();
147 
148  void _receiveRequest();
149  void _receiveRequestFrom(const unsigned int &receptorEmitting);
150  int _receiveRequestOnce();
151  int _receiveRequestOnceFrom(const unsigned int &receptorEmitting);
152 
153 public:
154 
155  vpNetwork();
156  virtual ~vpNetwork();
157 
158  void addDecodingRequest(vpRequest *);
159 
160  int getReceptorIndex(const char *name);
161 
169  std::string getRequestIdFromIndex(const int &ind){
170  if(ind >= (int)request_list.size() || ind < 0)
171  return "";
172  return request_list[(unsigned)ind]->getId();
173  }
174 
182  unsigned int getMaxSizeReceivedMessage(){ return max_size_message; }
183 
184  void print(const char *id = "");
185 
186  template<typename T>
187  int receive(T* object, const unsigned int &sizeOfObject = sizeof(T));
188  template<typename T>
189  int receiveFrom(T* object, const unsigned int &receptorEmitting, const unsigned int &sizeOfObject = sizeof(T));
190 
191  std::vector<int> receiveRequest();
192  std::vector<int> receiveRequestFrom(const unsigned int &receptorEmitting);
193  int receiveRequestOnce();
194  int receiveRequestOnceFrom(const unsigned int &receptorEmitting);
195 
196  std::vector<int> receiveAndDecodeRequest();
197  std::vector<int> receiveAndDecodeRequestFrom(const unsigned int &receptorEmitting);
198  int receiveAndDecodeRequestOnce();
199  int receiveAndDecodeRequestOnceFrom(const unsigned int &receptorEmitting);
200 
201  void removeDecodingRequest(const char *);
202 
203  template<typename T>
204  int send(T* object, const int unsigned &sizeOfObject = sizeof(T));
205  template<typename T>
206  int sendTo(T* object, const unsigned int &dest, const unsigned int &sizeOfObject = sizeof(T));
207 
208  int sendRequest(vpRequest &req);
209  int sendRequestTo(vpRequest &req, const unsigned int &dest);
210 
211  int sendAndEncodeRequest(vpRequest &req);
212  int sendAndEncodeRequestTo(vpRequest &req, const unsigned int &dest);
213 
221  void setMaxSizeReceivedMessage(const unsigned int &s){ max_size_message = s;}
222 
231  void setTimeoutSec(const long &sec){ tv_sec = sec; }
232 
241  void setTimeoutUSec(const long &usec){ tv_usec = usec; }
242 
248  void setVerbose(const bool &mode){ verboseMode = mode; }
249 };
250 
251 //######## Definition of Template Functions ########
252 //# #
253 //##################################################
254 
274 template<typename T>
275 int vpNetwork::receive(T* object, const unsigned int &sizeOfObject)
276 {
277  if(receptor_list.size() == 0)
278  {
279  if(verboseMode)
280  vpTRACE( "No receptor" );
281  return -1;
282  }
283 
284  tv.tv_sec = tv_sec;
285  tv.tv_usec = tv_usec;
286 
287  FD_ZERO(&readFileDescriptor);
288 
289  for(unsigned int i=0; i<receptor_list.size(); i++){
290  FD_SET((unsigned int)receptor_list[i].socketFileDescriptorReceptor,&readFileDescriptor);
291 
292  if(i == 0)
293  socketMax = receptor_list[i].socketFileDescriptorReceptor;
294 
295  if(socketMax < receptor_list[i].socketFileDescriptorReceptor) socketMax = receptor_list[i].socketFileDescriptorReceptor;
296  }
297 
298  int value = select((int)socketMax+1,&readFileDescriptor,NULL,NULL,&tv);
299  int numbytes = 0;
300 
301  if(value == -1){
302  if(verboseMode)
303  vpERROR_TRACE( "Select error" );
304  return -1;
305  }
306  else if(value == 0){
307  //Timeout
308  return 0;
309  }
310  else{
311  for(unsigned int i=0; i<receptor_list.size(); i++){
312  if(FD_ISSET((unsigned int)receptor_list[i].socketFileDescriptorReceptor,&readFileDescriptor)){
313 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
314  numbytes = recv(receptor_list[i].socketFileDescriptorReceptor, (char*)(void*)object, sizeOfObject, 0);
315 #else
316  numbytes = recv((unsigned int)receptor_list[i].socketFileDescriptorReceptor, (char*)(void*)object, (int)sizeOfObject, 0);
317 #endif
318  if(numbytes <= 0)
319  {
320  std::cout << "Disconnected : " << inet_ntoa(receptor_list[i].receptorAddress.sin_addr) << std::endl;
321  receptor_list.erase(receptor_list.begin()+(int)i);
322  return numbytes;
323  }
324 
325  break;
326  }
327  }
328  }
329 
330  return numbytes;
331 }
332 
354 template<typename T>
355 int vpNetwork::receiveFrom(T* object, const unsigned int &receptorEmitting, const unsigned int &sizeOfObject)
356 {
357  if(receptor_list.size() == 0 || receptorEmitting > (unsigned int)receptor_list.size()-1 )
358  {
359  if(verboseMode)
360  vpTRACE( "No receptor at the specified index" );
361  return -1;
362  }
363 
364  tv.tv_sec = tv_sec;
365  tv.tv_usec = tv_usec;
366 
367  FD_ZERO(&readFileDescriptor);
368 
369  socketMax = receptor_list[receptorEmitting].socketFileDescriptorReceptor;
370  FD_SET((unsigned int)receptor_list[receptorEmitting].socketFileDescriptorReceptor,&readFileDescriptor);
371 
372  int value = select((int)socketMax+1,&readFileDescriptor,NULL,NULL,&tv);
373  int numbytes = 0;
374 
375  if(value == -1){
376  if(verboseMode)
377  vpERROR_TRACE( "Select error" );
378  return -1;
379  }
380  else if(value == 0){
381  //timeout
382  return 0;
383  }
384  else{
385  if(FD_ISSET((unsigned int)receptor_list[receptorEmitting].socketFileDescriptorReceptor,&readFileDescriptor)){
386 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
387  numbytes = recv(receptor_list[receptorEmitting].socketFileDescriptorReceptor, (char*)(void*)object, sizeOfObject, 0);
388 #else
389  numbytes = recv((unsigned int)receptor_list[receptorEmitting].socketFileDescriptorReceptor, (char*)(void*)object, (int)sizeOfObject, 0);
390 #endif
391  if(numbytes <= 0)
392  {
393  std::cout << "Disconnected : " << inet_ntoa(receptor_list[receptorEmitting].receptorAddress.sin_addr) << std::endl;
394  receptor_list.erase(receptor_list.begin()+(int)receptorEmitting);
395  return numbytes;
396  }
397  }
398  }
399 
400  return numbytes;
401 }
402 
423 template<typename T>
424 int vpNetwork::send(T* object, const unsigned int &sizeOfObject)
425 {
426  if(receptor_list.size() == 0)
427  {
428  if(verboseMode)
429  vpTRACE( "No receptor !" );
430  return 0;
431  }
432 
433  int flags = 0;
434 //#if ! defined(APPLE) && ! defined(SOLARIS) && ! defined(_WIN32)
435 #if defined(__linux__)
436  flags = MSG_NOSIGNAL; // Only for Linux
437 #endif
438 
439 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
440  return sendto(receptor_list[0].socketFileDescriptorReceptor, (const char*)(void*)object, sizeOfObject,
441  flags, (sockaddr*) &receptor_list[0].receptorAddress,receptor_list[0].receptorAddressSize);
442 #else
443  return sendto(receptor_list[0].socketFileDescriptorReceptor, (const char*)(void*)object, (int)sizeOfObject,
444  flags, (sockaddr*) &receptor_list[0].receptorAddress,receptor_list[0].receptorAddressSize);
445 #endif
446 
447 }
448 
470 template<typename T>
471 int vpNetwork::sendTo(T* object, const unsigned int &dest, const unsigned int &sizeOfObject)
472 {
473  if(receptor_list.size() == 0 || dest > (unsigned int)receptor_list.size()-1 )
474  {
475  if(verboseMode)
476  vpTRACE( "No receptor at the specified index." );
477  return 0;
478  }
479 
480  int flags = 0;
481 //#if ! defined(APPLE) && ! defined(SOLARIS) && ! defined(_WIN32)
482 #if defined(__linux__)
483  flags = MSG_NOSIGNAL; // Only for Linux
484 #endif
485 
486 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
487  return sendto(receptor_list[dest].socketFileDescriptorReceptor, (const char*)(void*)object, sizeOfObject,
488  flags, (sockaddr*) &receptor_list[dest].receptorAddress,receptor_list[dest].receptorAddressSize);
489 #else
490  return sendto(receptor_list[dest].socketFileDescriptorReceptor, (const char*)(void*)object, (int)sizeOfObject,
491  flags, (sockaddr*) &receptor_list[dest].receptorAddress,receptor_list[dest].receptorAddressSize);
492 #endif
493 }
494 
495 #endif
unsigned int max_size_message
Definition: vpNetwork.h:129
std::string separator
Definition: vpNetwork.h:130
void setMaxSizeReceivedMessage(const unsigned int &s)
Definition: vpNetwork.h:221
std::string beginning
Definition: vpNetwork.h:131
This the request that will transit on the network.
Definition: vpRequest.h:130
std::vector< vpRequest * > request_list
Definition: vpNetwork.h:127
socklen_t receptorAddressSize
Definition: vpNetwork.h:86
std::string getRequestIdFromIndex(const int &ind)
Definition: vpNetwork.h:169
fd_set readFileDescriptor
Definition: vpNetwork.h:119
int socketFileDescriptorEmitter
Definition: vpNetwork.h:100
#define vpERROR_TRACE
Definition: vpDebug.h:391
This class represents a Transmission Control Protocol (TCP) network.
Definition: vpNetwork.h:79
int socketFileDescriptorReceptor
Definition: vpNetwork.h:85
int send(T *object, const int unsigned &sizeOfObject=sizeof(T))
int socketMax
Definition: vpNetwork.h:121
unsigned int getMaxSizeReceivedMessage()
Definition: vpNetwork.h:182
std::string end
Definition: vpNetwork.h:132
#define vpTRACE
Definition: vpDebug.h:414
vpEmitter emitter
Definition: vpNetwork.h:117
int receive(T *object, const unsigned int &sizeOfObject=sizeof(T))
Definition: vpNetwork.h:275
void setTimeoutUSec(const long &usec)
Definition: vpNetwork.h:241
long tv_sec
Definition: vpNetwork.h:138
bool verboseMode
Definition: vpNetwork.h:141
struct timeval tv
Definition: vpNetwork.h:137
std::vector< vpReceptor > receptor_list
Definition: vpNetwork.h:118
long tv_usec
Definition: vpNetwork.h:139
void setVerbose(const bool &mode)
Definition: vpNetwork.h:248
void setTimeoutSec(const long &sec)
Definition: vpNetwork.h:231
std::string currentMessageReceived
Definition: vpNetwork.h:135
int sendTo(T *object, const unsigned int &dest, const unsigned int &sizeOfObject=sizeof(T))
Definition: vpNetwork.h:471
std::string param_sep
Definition: vpNetwork.h:133
std::string receptorIP
Definition: vpNetwork.h:92
int receiveFrom(T *object, const unsigned int &receptorEmitting, const unsigned int &sizeOfObject=sizeof(T))
Definition: vpNetwork.h:355