ViSP  2.9.0
vpNetwork.h
1 /****************************************************************************
2  *
3  * $Id: vpNetwork.h 4632 2014-02-03 17:06:40Z fspindle $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2014 by INRIA. All rights reserved.
7  *
8  * This software is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * ("GPL") version 2 as published by the Free Software Foundation.
11  * See the file LICENSE.txt at the root directory of this source
12  * distribution for additional information about the GNU GPL.
13  *
14  * For using ViSP with software that can not be combined with the GNU
15  * GPL, please contact INRIA about acquiring a ViSP Professional
16  * Edition License.
17  *
18  * See http://www.irisa.fr/lagadic/visp/visp.html for more information.
19  *
20  * This software was developed at:
21  * INRIA Rennes - Bretagne Atlantique
22  * Campus Universitaire de Beaulieu
23  * 35042 Rennes Cedex
24  * France
25  * http://www.irisa.fr/lagadic
26  *
27  * If you have questions regarding the use of this file, please contact
28  * INRIA at visp@inria.fr
29  *
30  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
31  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
32  *
33  *
34  * Description:
35  * TCP Network
36  *
37  * Authors:
38  * Aurelien Yol
39  *
40  *****************************************************************************/
41 
42 #ifndef vpNetwork_H
43 #define vpNetwork_H
44 
45 #include <visp/vpConfig.h>
46 #include <visp/vpRequest.h>
47 
48 #include <vector>
49 #include <stdio.h>
50 #include <string.h>
51 #include <iostream>
52 
53 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
54 # include <unistd.h>
55 # include <sys/socket.h>
56 # include <netinet/in.h>
57 # include <arpa/inet.h>
58 # include <netdb.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 
83 class VISP_EXPORT vpNetwork
84 {
85 protected:
86 
87  struct vpReceptor{
88 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
89  int socketFileDescriptorReceptor;
90  socklen_t receptorAddressSize;
91 #else
94 #endif
95  struct sockaddr_in receptorAddress;
96  std::string receptorIP;
97 
98  vpReceptor() : socketFileDescriptorReceptor(0), receptorAddressSize(), receptorAddress(), receptorIP() {}
99  };
100 
101  struct vpEmitter{
102  struct sockaddr_in emitterAddress;
103 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
104  int socketFileDescriptorEmitter;
105 #else
107 #endif
108  vpEmitter() : emitterAddress(), socketFileDescriptorEmitter(0)
109  {
110  emitterAddress.sin_family = AF_INET;
111  emitterAddress.sin_addr.s_addr = INADDR_ANY;
112  emitterAddress.sin_port = 0;
113  socketFileDescriptorEmitter = 0;
114  }
115  };
116 
117  //######## PARAMETERS ########
118  //# #
119  //############################
120 
122  std::vector<vpReceptor> receptor_list;
124 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
125  int socketMax;
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  tv.tv_usec = tv_usec;
290 
291  FD_ZERO(&readFileDescriptor);
292 
293  for(unsigned int i=0; i<receptor_list.size(); i++){
294  FD_SET((unsigned int)receptor_list[i].socketFileDescriptorReceptor,&readFileDescriptor);
295 
296  if(i == 0)
297  socketMax = receptor_list[i].socketFileDescriptorReceptor;
298 
299  if(socketMax < receptor_list[i].socketFileDescriptorReceptor) socketMax = receptor_list[i].socketFileDescriptorReceptor;
300  }
301 
302  int value = select((int)socketMax+1,&readFileDescriptor,NULL,NULL,&tv);
303  int numbytes = 0;
304 
305  if(value == -1){
306  if(verboseMode)
307  vpERROR_TRACE( "Select error" );
308  return -1;
309  }
310  else if(value == 0){
311  //Timeout
312  return 0;
313  }
314  else{
315  for(unsigned int i=0; i<receptor_list.size(); i++){
316  if(FD_ISSET((unsigned int)receptor_list[i].socketFileDescriptorReceptor,&readFileDescriptor)){
317 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
318  numbytes = recv(receptor_list[i].socketFileDescriptorReceptor, (char*)(void*)object, sizeOfObject, 0);
319 #else
320  numbytes = recv((unsigned int)receptor_list[i].socketFileDescriptorReceptor, (char*)(void*)object, (int)sizeOfObject, 0);
321 #endif
322  if(numbytes <= 0)
323  {
324  std::cout << "Disconnected : " << inet_ntoa(receptor_list[i].receptorAddress.sin_addr) << std::endl;
325  receptor_list.erase(receptor_list.begin()+(int)i);
326  return numbytes;
327  }
328 
329  break;
330  }
331  }
332  }
333 
334  return numbytes;
335 }
336 
358 template<typename T>
359 int vpNetwork::receiveFrom(T* object, const unsigned int &receptorEmitting, const unsigned int &sizeOfObject)
360 {
361  if(receptor_list.size() == 0 || receptorEmitting > (int)receptor_list.size()-1 )
362  {
363  if(verboseMode)
364  vpTRACE( "No receptor at the specified index" );
365  return -1;
366  }
367 
368  tv.tv_sec = tv_sec;
369  tv.tv_usec = tv_usec;
370 
371  FD_ZERO(&readFileDescriptor);
372 
373  socketMax = receptor_list[receptorEmitting].socketFileDescriptorReceptor;
374  FD_SET((unsigned int)receptor_list[receptorEmitting].socketFileDescriptorReceptor,&readFileDescriptor);
375 
376  int value = select((int)socketMax+1,&readFileDescriptor,NULL,NULL,&tv);
377  int numbytes = 0;
378 
379  if(value == -1){
380  if(verboseMode)
381  vpERROR_TRACE( "Select error" );
382  return -1;
383  }
384  else if(value == 0){
385  //timeout
386  return 0;
387  }
388  else{
389  if(FD_ISSET((unsigned int)receptor_list[receptorEmitting].socketFileDescriptorReceptor,&readFileDescriptor)){
390 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
391  numbytes = recv(receptor_list[receptorEmitting].socketFileDescriptorReceptor, (char*)(void*)object, sizeOfObject, 0);
392 #else
393  numbytes = recv((unsigned int)receptor_list[receptorEmitting].socketFileDescriptorReceptor, (char*)(void*)object, (int)sizeOfObject, 0);
394 #endif
395  if(numbytes <= 0)
396  {
397  std::cout << "Disconnected : " << inet_ntoa(receptor_list[receptorEmitting].receptorAddress.sin_addr) << std::endl;
398  receptor_list.erase(receptor_list.begin()+(int)receptorEmitting);
399  return numbytes;
400  }
401  }
402  }
403 
404  return numbytes;
405 }
406 
427 template<typename T>
428 int vpNetwork::send(T* object, const unsigned int &sizeOfObject)
429 {
430  if(receptor_list.size() == 0)
431  {
432  if(verboseMode)
433  vpTRACE( "No receptor !" );
434  return 0;
435  }
436 
437  int flags = 0;
438 //#if ! defined(APPLE) && ! defined(SOLARIS) && ! defined(_WIN32)
439 #if defined(__linux__)
440  flags = MSG_NOSIGNAL; // Only for Linux
441 #endif
442 
443 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
444  return sendto(receptor_list[0].socketFileDescriptorReceptor, (const char*)(void*)object, sizeOfObject,
445  flags, (sockaddr*) &receptor_list[0].receptorAddress,receptor_list[0].receptorAddressSize);
446 #else
447  return sendto(receptor_list[0].socketFileDescriptorReceptor, (const char*)(void*)object, (int)sizeOfObject,
448  flags, (sockaddr*) &receptor_list[0].receptorAddress,receptor_list[0].receptorAddressSize);
449 #endif
450 
451 }
452 
474 template<typename T>
475 int vpNetwork::sendTo(T* object, const unsigned int &dest, const unsigned int &sizeOfObject)
476 {
477  if(receptor_list.size() == 0 || dest > (int)receptor_list.size()-1 )
478  {
479  if(verboseMode)
480  vpTRACE( "No receptor at the specified index." );
481  return 0;
482  }
483 
484  int flags = 0;
485 //#if ! defined(APPLE) && ! defined(SOLARIS) && ! defined(_WIN32)
486 #if defined(__linux__)
487  flags = MSG_NOSIGNAL; // Only for Linux
488 #endif
489 
490 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
491  return sendto(receptor_list[dest].socketFileDescriptorReceptor, (const char*)(void*)object, sizeOfObject,
492  flags, (sockaddr*) &receptor_list[dest].receptorAddress,receptor_list[dest].receptorAddressSize);
493 #else
494  return sendto(receptor_list[dest].socketFileDescriptorReceptor, (const char*)(void*)object, (int)sizeOfObject,
495  flags, (sockaddr*) &receptor_list[dest].receptorAddress,receptor_list[dest].receptorAddressSize);
496 #endif
497 }
498 
499 #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:134
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:395
#define vpTRACE
Definition: vpDebug.h:418
This class represents a Transmission Control Protocol (TCP) network.
Definition: vpNetwork.h:83
int send(T *object, const int unsigned &sizeOfObject=sizeof(T))
SOCKET socketMax
Definition: vpNetwork.h:127
unsigned int getMaxSizeReceivedMessage()
Definition: vpNetwork.h:186
std::string end
Definition: vpNetwork.h:136
SOCKET socketFileDescriptorEmitter
Definition: vpNetwork.h:106
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
SOCKET socketFileDescriptorReceptor
Definition: vpNetwork.h:92
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:475
std::string param_sep
Definition: vpNetwork.h:137
std::string receptorIP
Definition: vpNetwork.h:96
int receiveFrom(T *object, const unsigned int &receptorEmitting, const unsigned int &sizeOfObject=sizeof(T))
Definition: vpNetwork.h:359