Visual Servoing Platform  version 3.0.0
vpNetwork.cpp
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 
39 #include <visp3/core/vpNetwork.h>
40 
42  : emitter(), receptor_list(), readFileDescriptor(), socketMax(0), request_list(),
43  max_size_message(999999), separator("[*@*]"), beginning("[*start*]"), end("[*end*]"),
44  param_sep("[*|*]"), currentMessageReceived(), tv(), tv_sec(0), tv_usec(10),
45  verboseMode(false)
46 {
47  tv.tv_sec = tv_sec;
48  tv.tv_usec = tv_usec;
49 
50 #if defined(_WIN32)
51  //Enable the sockets to be used
52  //Note that: if we were using "winsock.h" instead of "winsock2.h" we would had to use:
53  //WSAStartup(MAKEWORD(1,0), &WSAData);
54  WSADATA WSAData;
55  WSAStartup(MAKEWORD(2,0), &WSAData);
56 #endif
57 }
58 
60 {
61 #if defined(_WIN32)
62  WSACleanup();
63 #endif
64 }
65 
78 {
79  bool alreadyHas = false;
80 
81  for(unsigned int i = 0 ; i < request_list.size() ; i++)
82  if(request_list[i]->getId() == req->getId()){
83  alreadyHas = true;
84  break;
85  }
86 
87  if(alreadyHas)
88  std::cout << "Server already has one request with the similar ID. Request hasn't been added." << std::endl;
89  else
90  request_list.push_back(req);
91 }
92 
101 {
102  for(unsigned int i = 0 ; i < request_list.size() ; i++)
103  {
104  if(request_list[i]->getId() == id)
105  {
106  request_list.erase(request_list.begin()+(int)i);
107  break;
108  }
109  }
110 }
111 
117 void vpNetwork::print(const char *id)
118 {
119  for(unsigned int i = 0 ; i < receptor_list.size() ; i++)
120  {
121  std::cout << id << i << " : " << inet_ntoa(receptor_list[i].receptorAddress.sin_addr) << std::endl;
122  }
123 }
124 
132 int vpNetwork::getReceptorIndex(const char *name)
133 {
134  struct hostent *server = gethostbyname(name);
135 
136  if ( server == NULL )
137  {
138  std::string noSuchHostMessage( "ERROR, " );
139  noSuchHostMessage.append( name );
140  noSuchHostMessage.append( ": no such host\n" );
141  vpERROR_TRACE( noSuchHostMessage.c_str(), "vpNetwork::getReceptorIndex()" );
142  return -1;
143  }
144 
145  std::string ip = inet_ntoa(*(in_addr *)server->h_addr);
146 
147  for(int i = 0 ; i < (int)receptor_list.size() ; i++)
148  {
149  if(receptor_list[(unsigned)i].receptorIP == ip)
150  return i;
151  }
152 
153  return -1;
154 }
155 
170 {
171  return sendRequestTo(req,0);
172 }
173 
188 int vpNetwork::sendRequestTo(vpRequest &req, const unsigned int &dest)
189 {
190  int size = (int)receptor_list.size();
191  int sizeMinusOne = (int)receptor_list.size()-1;
192  if(size == 0 || dest > (unsigned)sizeMinusOne)
193  {
194  if(verboseMode)
195  vpTRACE( "Cannot Send Request! Bad Index" );
196  return 0;
197  }
198 
199  std::string message = beginning + req.getId() + separator;
200 
201  if(req.size() != 0){
202  message += req[0];
203 
204  for(unsigned int i = 1 ; i < req.size() ; i++){
205  message += param_sep + req[i];
206  }
207  }
208 
209  message += end;
210 
211  int flags = 0;
212 //#if ! defined(APPLE) && ! defined(SOLARIS) && ! defined(_WIN32)
213 #if defined(__linux__)
214  flags = MSG_NOSIGNAL; // Only for Linux
215 #endif
216 
217 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
218  int value = sendto(receptor_list[dest].socketFileDescriptorReceptor, message.c_str(), message.size(), flags,
219  (sockaddr*) &receptor_list[dest].receptorAddress,receptor_list[dest].receptorAddressSize);
220 #else
221  int value = sendto((unsigned)receptor_list[dest].socketFileDescriptorReceptor, message.c_str(), (int)message.size(), flags,
222  (sockaddr*) &receptor_list[dest].receptorAddress,receptor_list[dest].receptorAddressSize);
223 #endif
224 
225  return value;
226 }
227 
242 {
243  req.encode();
244  return sendRequest(req);
245 }
246 
261 int vpNetwork::sendAndEncodeRequestTo(vpRequest &req, const unsigned int &dest)
262 {
263  req.encode();
264  return sendRequestTo(req,dest);
265 }
266 
281 std::vector<int> vpNetwork::receiveRequest()
282 {
283  _receiveRequest();
284  return _handleRequests();
285 }
286 
303 std::vector<int> vpNetwork::receiveRequestFrom(const unsigned int &receptorEmitting)
304 {
305  _receiveRequestFrom(receptorEmitting);
306  return _handleRequests();
307 }
308 
328 {
329  _receiveRequestOnce();
330  return _handleFirstRequest();
331 }
332 
353 int vpNetwork::receiveRequestOnceFrom(const unsigned int &receptorEmitting)
354 {
355  _receiveRequestOnceFrom(receptorEmitting);
356  return _handleFirstRequest();
357 }
358 
374 {
375  std::vector<int> res = receiveRequest();
376  for(unsigned int i = 0 ; i < res.size() ; i++)
377  if(res[i] != -1)
378  request_list[(unsigned)res[i]]->decode();
379 
380  return res;
381 }
382 
399 std::vector<int> vpNetwork::receiveAndDecodeRequestFrom(const unsigned int &receptorEmitting)
400 {
401  std::vector<int> res = receiveRequestFrom(receptorEmitting);
402  for(unsigned int i = 0 ; i < res.size() ; i++)
403  if(res[i] != -1)
404  request_list[(unsigned)res[i]]->decode();
405 
406  return res;
407 }
408 
429 {
430  int res = receiveRequestOnce();
431  if(res != -1)
432  request_list[(unsigned)res]->decode();
433 
434  return res;
435 }
436 
458 int vpNetwork::receiveAndDecodeRequestOnceFrom(const unsigned int &receptorEmitting)
459 {
460  int res = receiveRequestOnceFrom(receptorEmitting);
461  if(res != -1)
462  request_list[(unsigned)res]->decode();
463 
464  return res;
465 }
466 
467 
468 //######## Definition of Template Functions ########
469 //# #
470 //##################################################
471 
472 
483 std::vector<int> vpNetwork::_handleRequests()
484 {
485  std::vector<int> resIndex;
486  int index = _handleFirstRequest();
487 
488  while(index != -1)
489  {
490  resIndex.push_back(index);
491  index = _handleFirstRequest();
492  }
493 
494  return resIndex;
495 }
496 
507 int vpNetwork::_handleFirstRequest()
508 {
509  size_t indStart = currentMessageReceived.find(beginning);
510  size_t indSep = currentMessageReceived.find(separator);
511  size_t indEnd = currentMessageReceived.find(end);
512 
513  if (indStart == std::string::npos && indSep == std::string::npos && indEnd == std::string::npos)
514  {
515  if(currentMessageReceived.size() != 0)
516  currentMessageReceived.clear();
517 
518  if(verboseMode)
519  vpTRACE("Incorrect message");
520 
521  return -1;
522  }
523 
524  if(indStart == std::string::npos || indSep == std::string::npos || indEnd == std::string::npos)
525  return -1;
526 
527  if(indEnd < indStart)
528  {
529  if(verboseMode)
530  vpTRACE("Incorrect message");
531  currentMessageReceived.erase((unsigned)indStart,indEnd+end.size());
532  return -1;
533  }
534 
535  size_t indStart2 = currentMessageReceived.find(beginning,indStart+1);
536  if(indStart2 != std::string::npos && indStart2 < indEnd)
537  {
538  if(verboseMode)
539  vpTRACE("Incorrect message");
540  currentMessageReceived.erase((unsigned)indStart,(unsigned)indStart2);
541  return -1;
542  }
543 
544  size_t deb = indStart + beginning.size();
545  std::string id = currentMessageReceived.substr((unsigned)deb, indSep - deb);
546 
547  deb = indSep+separator.size();
548  std::string params = currentMessageReceived.substr((unsigned)deb, (unsigned)(indEnd - deb));
549 
550 // std::cout << "Handling : " << currentMessageReceived.substr(indStart, indEnd+end.size() - indStart) << std::endl;
551 
552  int indRequest = 0;
553  bool hasBeenFound = false;
554  for(unsigned int i = 0 ; i < request_list.size() ; i++)
555  {
556  if(id == request_list[i]->getId()){
557  hasBeenFound = true;
558  request_list[i]->clear();
559  indRequest = (int)i;
560  break;
561  }
562  }
563 
564  if(!hasBeenFound){
565  //currentMessageReceived.erase(indStart,indEnd+end.size());
566  if(verboseMode)
567  vpTRACE("No request corresponds to the received message");
568  return -1;
569  }
570 
571  size_t indDebParam = indSep + separator.size();
572  size_t indEndParam = currentMessageReceived.find(param_sep,indDebParam);
573 
574  std::string param;
575  while(indEndParam != std::string::npos || indEndParam < indEnd)
576  {
577  param = currentMessageReceived.substr((unsigned)indDebParam,(unsigned)(indEndParam - indDebParam));
578  request_list[(unsigned)indRequest]->addParameter(param);
579  indDebParam = indEndParam+param_sep.size();
580  indEndParam = currentMessageReceived.find(param_sep,indDebParam);
581  }
582 
583  param = currentMessageReceived.substr((unsigned)indDebParam, indEnd - indDebParam);
584  request_list[(unsigned)indRequest]->addParameter(param);
585  currentMessageReceived.erase(indStart,indEnd+end.size());
586 
587  return indRequest;
588 }
589 
604 void vpNetwork::_receiveRequest()
605 {
606  while(_receiveRequestOnce() > 0) {};
607 }
608 
625 void vpNetwork::_receiveRequestFrom(const unsigned int &receptorEmitting)
626 {
627  while(_receiveRequestOnceFrom(receptorEmitting) > 0) {};
628 }
629 
648 int vpNetwork::_receiveRequestOnce()
649 {
650  if(receptor_list.size() == 0)
651  {
652  if(verboseMode)
653  vpTRACE( "No Receptor!" );
654  return -1;
655  }
656 
657  tv.tv_sec = tv_sec;
658  tv.tv_usec = tv_usec;
659 
660  FD_ZERO(&readFileDescriptor);
661 
662  for(unsigned int i=0; i<receptor_list.size(); i++){
663  if(i == 0)
664  socketMax = receptor_list[i].socketFileDescriptorReceptor;
665 
666  FD_SET((unsigned)receptor_list[i].socketFileDescriptorReceptor,&readFileDescriptor);
667  if(socketMax < receptor_list[i].socketFileDescriptorReceptor) socketMax = receptor_list[i].socketFileDescriptorReceptor;
668  }
669 
670  int value = select((int)socketMax+1,&readFileDescriptor,NULL,NULL,&tv);
671  int numbytes = 0;
672 
673  if(value == -1){
674  if(verboseMode)
675  vpERROR_TRACE( "Select error" );
676  return -1;
677  }
678  else if(value == 0){
679  //Timeout
680  return 0;
681  }
682  else{
683  for(unsigned int i=0; i<receptor_list.size(); i++){
684  if(FD_ISSET((unsigned int)receptor_list[i].socketFileDescriptorReceptor,&readFileDescriptor)){
685  char *buf = new char [max_size_message];
686 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
687  numbytes=recv(receptor_list[i].socketFileDescriptorReceptor, buf, max_size_message, 0);
688 #else
689  numbytes=recv((unsigned int)receptor_list[i].socketFileDescriptorReceptor, buf, (int)max_size_message, 0);
690 #endif
691 
692  if(numbytes <= 0)
693  {
694  std::cout << "Disconnected : " << inet_ntoa(receptor_list[i].receptorAddress.sin_addr) << std::endl;
695  receptor_list.erase(receptor_list.begin()+(int)i);
696  delete [] buf;
697  return numbytes;
698  }
699  else if(numbytes > 0){
700  std::string returnVal(buf, (unsigned int)numbytes);
701  currentMessageReceived.append(returnVal);
702  }
703  delete [] buf;
704  break;
705  }
706  }
707  }
708 
709  return numbytes;
710 }
711 
732 int vpNetwork::_receiveRequestOnceFrom(const unsigned int &receptorEmitting)
733 {
734  int size = (int)receptor_list.size();
735  int sizeMinusOne = (int)receptor_list.size()-1;
736  if(size == 0 || receptorEmitting > (unsigned)sizeMinusOne )
737  {
738  if(verboseMode)
739  vpTRACE( "No receptor at the specified index!" );
740  return -1;
741  }
742 
743  tv.tv_sec = tv_sec;
744  tv.tv_usec = tv_usec;
745 
746  FD_ZERO(&readFileDescriptor);
747 
748  socketMax = receptor_list[receptorEmitting].socketFileDescriptorReceptor;
749  FD_SET((unsigned int)receptor_list[receptorEmitting].socketFileDescriptorReceptor,&readFileDescriptor);
750 
751  int value = select((int)socketMax+1,&readFileDescriptor,NULL,NULL,&tv);
752  int numbytes = 0;
753  if(value == -1){
754  if(verboseMode)
755  vpERROR_TRACE( "Select error" );
756  return -1;
757  }
758  else if(value == 0){
759  //Timeout
760  return 0;
761  }
762  else{
763  if(FD_ISSET((unsigned int)receptor_list[receptorEmitting].socketFileDescriptorReceptor,&readFileDescriptor)){
764  char *buf = new char [max_size_message];
765 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
766  numbytes=recv(receptor_list[receptorEmitting].socketFileDescriptorReceptor, buf, max_size_message, 0);
767 #else
768  numbytes=recv((unsigned int)receptor_list[receptorEmitting].socketFileDescriptorReceptor, buf, (int)max_size_message, 0);
769 #endif
770  if(numbytes <= 0)
771  {
772  std::cout << "Disconnected : " << inet_ntoa(receptor_list[receptorEmitting].receptorAddress.sin_addr) << std::endl;
773  receptor_list.erase(receptor_list.begin()+(int)receptorEmitting);
774  delete [] buf;
775  return numbytes;
776  }
777  else if(numbytes > 0){
778  std::string returnVal(buf, (unsigned int)numbytes);
779  currentMessageReceived.append(returnVal);
780  }
781  delete [] buf;
782  }
783  }
784 
785  return numbytes;
786 }
787 
788 
789 
unsigned int max_size_message
Definition: vpNetwork.h:129
int receiveRequestOnce()
Definition: vpNetwork.cpp:327
std::string separator
Definition: vpNetwork.h:130
int receiveRequestOnceFrom(const unsigned int &receptorEmitting)
Definition: vpNetwork.cpp:353
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
fd_set readFileDescriptor
Definition: vpNetwork.h:119
void print(const char *id="")
Definition: vpNetwork.cpp:117
#define vpERROR_TRACE
Definition: vpDebug.h:391
int receiveAndDecodeRequestOnceFrom(const unsigned int &receptorEmitting)
Definition: vpNetwork.cpp:458
int sendRequestTo(vpRequest &req, const unsigned int &dest)
Definition: vpNetwork.cpp:188
std::vector< int > receiveRequestFrom(const unsigned int &receptorEmitting)
Definition: vpNetwork.cpp:303
std::vector< int > receiveAndDecodeRequestFrom(const unsigned int &receptorEmitting)
Definition: vpNetwork.cpp:399
virtual void encode()=0
int socketMax
Definition: vpNetwork.h:121
virtual ~vpNetwork()
Definition: vpNetwork.cpp:59
std::vector< int > receiveAndDecodeRequest()
Definition: vpNetwork.cpp:373
std::string end
Definition: vpNetwork.h:132
#define vpTRACE
Definition: vpDebug.h:414
int sendAndEncodeRequestTo(vpRequest &req, const unsigned int &dest)
Definition: vpNetwork.cpp:261
unsigned int size()
Definition: vpRequest.h:202
int receiveAndDecodeRequestOnce()
Definition: vpNetwork.cpp:428
int sendAndEncodeRequest(vpRequest &req)
Definition: vpNetwork.cpp:241
long tv_sec
Definition: vpNetwork.h:138
bool verboseMode
Definition: vpNetwork.h:141
std::vector< int > receiveRequest()
Definition: vpNetwork.cpp:281
std::string getId()
Definition: vpRequest.h:186
struct timeval tv
Definition: vpNetwork.h:137
std::vector< vpReceptor > receptor_list
Definition: vpNetwork.h:118
int sendRequest(vpRequest &req)
Definition: vpNetwork.cpp:169
long tv_usec
Definition: vpNetwork.h:139
void removeDecodingRequest(const char *)
Definition: vpNetwork.cpp:100
std::string currentMessageReceived
Definition: vpNetwork.h:135
int getReceptorIndex(const char *name)
Definition: vpNetwork.cpp:132
void addDecodingRequest(vpRequest *)
Definition: vpNetwork.cpp:77
std::string param_sep
Definition: vpNetwork.h:133