ViSP  2.8.0
vpNetwork.cpp
1 /****************************************************************************
2  *
3  * $Id: vpNetwork.cpp 4056 2013-01-05 13:04:42Z fspindle $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2013 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 
43 #include <visp/vpNetwork.h>
44 
46 {
47  separator = "[*@*]";
48  beginning = "[*start*]";
49  end = "[*end*]";
50  param_sep = "[*|*]";
51  max_size_message = 999999;
52 
53  tv_sec = 0;
54  tv_usec = 10;
55 
56  verboseMode = false;
57 
58 #ifdef WIN32
59  //Enable the sockets to be used
60  //Note that: if we were using "winsock.h" instead of "winsock2.h" we would had to use:
61  //WSAStartup(MAKEWORD(1,0), &WSAData);
62  WSADATA WSAData;
63  WSAStartup(MAKEWORD(2,0), &WSAData);
64 #endif
65 }
66 
68 {
69 #ifdef WIN32
70  WSACleanup();
71 #endif
72 }
73 
86 {
87  bool alreadyHas = false;
88 
89  for(unsigned int i = 0 ; i < request_list.size() ; i++)
90  if(request_list[i]->getId() == req->getId()){
91  alreadyHas = true;
92  break;
93  }
94 
95  if(alreadyHas)
96  std::cout << "Server already has one request with the similar ID. Request hasn't been added." << std::endl;
97  else
98  request_list.push_back(req);
99 }
100 
109 {
110  for(unsigned int i = 0 ; i < request_list.size() ; i++)
111  {
112  if(request_list[i]->getId() == id)
113  {
114  request_list.erase(request_list.begin()+(int)i);
115  break;
116  }
117  }
118 }
119 
125 void vpNetwork::print(const char *id)
126 {
127  for(unsigned int i = 0 ; i < receptor_list.size() ; i++)
128  {
129  std::cout << id << i << " : " << inet_ntoa(receptor_list[i].receptorAddress.sin_addr) << std::endl;
130  }
131 }
132 
140 int vpNetwork::getReceptorIndex(const char *name)
141 {
142  struct hostent *server = gethostbyname(name);
143 
144  if ( server == NULL )
145  {
146  std::string noSuchHostMessage( "ERROR, " );
147  noSuchHostMessage.append( name );
148  noSuchHostMessage.append( ": no such host\n" );
149  vpERROR_TRACE( noSuchHostMessage.c_str(), "vpClient::getReceptorIndex()" );
150  }
151 
152  std::string ip = inet_ntoa(*(in_addr *)server->h_addr);
153 
154  for(int i = 0 ; i < (int)receptor_list.size() ; i++)
155  {
156  if(receptor_list[(unsigned)i].receptorIP == ip)
157  return i;
158  }
159 
160  return -1;
161 }
162 
177 {
178  return sendRequestTo(req,0);
179 }
180 
195 int vpNetwork::sendRequestTo(vpRequest &req, const unsigned int &dest)
196 {
197  int size = (int)receptor_list.size();
198  int sizeMinusOne = (int)receptor_list.size()-1;
199  if(size == 0 || dest > (unsigned)sizeMinusOne)
200  {
201  if(verboseMode)
202  vpTRACE( "Cannot Send Request! Bad Index" );
203  return 0;
204  }
205 
206  std::string message = beginning + req.getId() + separator;
207 
208  if(req.size() != 0){
209  message += req[0];
210 
211  for(unsigned int i = 1 ; i < req.size() ; i++){
212  message += param_sep + req[i];
213  }
214  }
215 
216  message += end;
217 
218  int flags = 0;
219 #if ! defined(APPLE) && ! defined(WIN32)
220  flags = MSG_NOSIGNAL; // Only for Linux
221 #endif
222 
223 #ifdef UNIX
224  int value = sendto(receptor_list[dest].socketFileDescriptorReceptor, message.c_str(), message.size(), flags,
225  (sockaddr*) &receptor_list[dest].receptorAddress,receptor_list[dest].receptorAddressSize);
226 #else
227  int value = sendto((unsigned)receptor_list[dest].socketFileDescriptorReceptor, message.c_str(), (int)message.size(), flags,
228  (sockaddr*) &receptor_list[dest].receptorAddress,receptor_list[dest].receptorAddressSize);
229 #endif
230 
231  return value;
232 }
233 
248 {
249  req.encode();
250  return sendRequest(req);
251 }
252 
267 int vpNetwork::sendAndEncodeRequestTo(vpRequest &req, const unsigned int &dest)
268 {
269  req.encode();
270  return sendRequestTo(req,dest);
271 }
272 
287 std::vector<int> vpNetwork::receiveRequest()
288 {
289  _receiveRequest();
290  return _handleRequests();
291 }
292 
309 std::vector<int> vpNetwork::receiveRequestFrom(const unsigned int &receptorEmitting)
310 {
311  _receiveRequestFrom(receptorEmitting);
312  return _handleRequests();
313 }
314 
334 {
335  _receiveRequestOnce();
336  return _handleFirstRequest();
337 }
338 
359 int vpNetwork::receiveRequestOnceFrom(const unsigned int &receptorEmitting)
360 {
361  _receiveRequestOnceFrom(receptorEmitting);
362  return _handleFirstRequest();
363 }
364 
380 {
381  std::vector<int> res = receiveRequest();
382  for(unsigned int i = 0 ; i < res.size() ; i++)
383  if(res[i] != -1)
384  request_list[(unsigned)res[i]]->decode();
385 
386  return res;
387 }
388 
405 std::vector<int> vpNetwork::receiveAndDecodeRequestFrom(const unsigned int &receptorEmitting)
406 {
407  std::vector<int> res = receiveRequestFrom(receptorEmitting);
408  for(unsigned int i = 0 ; i < res.size() ; i++)
409  if(res[i] != -1)
410  request_list[(unsigned)res[i]]->decode();
411 
412  return res;
413 }
414 
435 {
436  int res = receiveRequestOnce();
437  if(res != -1)
438  request_list[(unsigned)res]->decode();
439 
440  return res;
441 }
442 
464 int vpNetwork::receiveAndDecodeRequestOnceFrom(const unsigned int &receptorEmitting)
465 {
466  int res = receiveRequestOnceFrom(receptorEmitting);
467  if(res != -1)
468  request_list[(unsigned)res]->decode();
469 
470  return res;
471 }
472 
473 
474 //######## Definition of Template Functions ########
475 //# #
476 //##################################################
477 
478 
489 std::vector<int> vpNetwork::_handleRequests()
490 {
491  std::vector<int> resIndex;
492  int index = _handleFirstRequest();
493 
494  while(index != -1)
495  {
496  resIndex.push_back(index);
497  index = _handleFirstRequest();
498  }
499 
500  return resIndex;
501 }
502 
513 int vpNetwork::_handleFirstRequest()
514 {
515  size_t indStart = currentMessageReceived.find(beginning);
516  size_t indSep = currentMessageReceived.find(separator);
517  size_t indEnd = currentMessageReceived.find(end);
518 
519  if (indStart == std::string::npos && indSep == std::string::npos && indEnd == std::string::npos)
520  {
521  if(currentMessageReceived.size() != 0)
522  currentMessageReceived.clear();
523 
524  if(verboseMode)
525  vpTRACE("Incorrect message");
526 
527  return -1;
528  }
529 
530  if(indStart == std::string::npos || indSep == std::string::npos || indEnd == std::string::npos)
531  return -1;
532 
533  if(indEnd < indStart)
534  {
535  if(verboseMode)
536  vpTRACE("Incorrect message");
537  currentMessageReceived.erase((unsigned)indStart,indEnd+end.size());
538  return -1;
539  }
540 
541  size_t indStart2 = currentMessageReceived.find(beginning,indStart+1);
542  if(indStart2 != std::string::npos && indStart2 < indEnd)
543  {
544  if(verboseMode)
545  vpTRACE("Incorrect message");
546  currentMessageReceived.erase((unsigned)indStart,(unsigned)indStart2);
547  return -1;
548  }
549 
550  size_t deb = indStart + beginning.size();
551  std::string id = currentMessageReceived.substr((unsigned)deb, indSep - deb);
552 
553  deb = indSep+separator.size();
554  std::string params = currentMessageReceived.substr((unsigned)deb, (unsigned)(indEnd - deb));
555 
556 // std::cout << "Handling : " << currentMessageReceived.substr(indStart, indEnd+end.size() - indStart) << std::endl;
557 
558  int indRequest = 0;
559  bool hasBeenFound = false;
560  for(unsigned int i = 0 ; i < request_list.size() ; i++)
561  {
562  if(id == request_list[i]->getId()){
563  hasBeenFound = true;
564  request_list[i]->clear();
565  indRequest = (int)i;
566  break;
567  }
568  }
569 
570  if(!hasBeenFound){
571  //currentMessageReceived.erase(indStart,indEnd+end.size());
572  if(verboseMode)
573  vpTRACE("No request corresponds to the received message");
574  return -1;
575  }
576 
577  size_t indDebParam = indSep + separator.size();
578  size_t indEndParam = currentMessageReceived.find(param_sep,indDebParam);
579 
580  std::string param;
581  while(indEndParam != std::string::npos)
582  {
583  param = currentMessageReceived.substr((unsigned)indDebParam,(unsigned)(indEndParam - indDebParam));
584  request_list[(unsigned)indRequest]->addParameter(param);
585  indDebParam = indEndParam+param_sep.size();
586  indEndParam = currentMessageReceived.find(param_sep,indDebParam);
587  }
588 
589  param = currentMessageReceived.substr((unsigned)indDebParam, indEnd - indDebParam);
590  request_list[(unsigned)indRequest]->addParameter(param);
591  currentMessageReceived.erase(indStart,indEnd+end.size());
592 
593  return indRequest;
594 }
595 
610 void vpNetwork::_receiveRequest()
611 {
612  while(_receiveRequestOnce() > 0) {};
613 }
614 
631 void vpNetwork::_receiveRequestFrom(const unsigned int &receptorEmitting)
632 {
633  while(_receiveRequestOnceFrom(receptorEmitting) > 0) {};
634 }
635 
654 int vpNetwork::_receiveRequestOnce()
655 {
656  if(receptor_list.size() == 0)
657  {
658  if(verboseMode)
659  vpTRACE( "No Receptor!" );
660  return -1;
661  }
662 
663  tv.tv_sec = tv_sec;
664  tv.tv_usec = tv_usec;
665 
666  FD_ZERO(&readFileDescriptor);
667 
668  for(unsigned int i=0; i<receptor_list.size(); i++){
669  if(i == 0)
670  socketMax = receptor_list[i].socketFileDescriptorReceptor;
671 
672  FD_SET((unsigned)receptor_list[i].socketFileDescriptorReceptor,&readFileDescriptor);
673  if(socketMax < receptor_list[i].socketFileDescriptorReceptor) socketMax = receptor_list[i].socketFileDescriptorReceptor;
674  }
675 
676  int value = select((int)socketMax+1,&readFileDescriptor,NULL,NULL,&tv);
677  int numbytes = 0;
678 
679  if(value == -1){
680  if(verboseMode)
681  vpERROR_TRACE( "Select error" );
682  return -1;
683  }
684  else if(value == 0){
685  //Timeout
686  return 0;
687  }
688  else{
689  for(unsigned int i=0; i<receptor_list.size(); i++){
690  if(FD_ISSET((unsigned int)receptor_list[i].socketFileDescriptorReceptor,&readFileDescriptor)){
691  char *buf = new char [max_size_message];
692 #ifdef UNIX
693  numbytes=recv(receptor_list[i].socketFileDescriptorReceptor, buf, max_size_message, 0);
694 #else
695  numbytes=recv((unsigned int)receptor_list[i].socketFileDescriptorReceptor, buf, (int)max_size_message, 0);
696 #endif
697 
698 
699  if(numbytes <= 0)
700  {
701  std::cout << "Disconnected : " << inet_ntoa(receptor_list[i].receptorAddress.sin_addr) << std::endl;
702  receptor_list.erase(receptor_list.begin()+(int)i);
703  return numbytes;
704  }
705  else if(numbytes > 0){
706  std::string returnVal(buf, (unsigned int)numbytes);
707  currentMessageReceived.append(returnVal);
708  }
709  delete [] buf;
710  break;
711  }
712  }
713  }
714 
715  return numbytes;
716 }
717 
738 int vpNetwork::_receiveRequestOnceFrom(const unsigned int &receptorEmitting)
739 {
740  int size = (int)receptor_list.size();
741  int sizeMinusOne = (int)receptor_list.size()-1;
742  if(size == 0 || receptorEmitting > (unsigned)sizeMinusOne )
743  {
744  if(verboseMode)
745  vpTRACE( "No receptor at the specified index!" );
746  return -1;
747  }
748 
749  tv.tv_sec = tv_sec;
750  tv.tv_usec = tv_usec;
751 
752  FD_ZERO(&readFileDescriptor);
753 
754  socketMax = receptor_list[receptorEmitting].socketFileDescriptorReceptor;
755  FD_SET((unsigned int)receptor_list[receptorEmitting].socketFileDescriptorReceptor,&readFileDescriptor);
756 
757  int value = select((int)socketMax+1,&readFileDescriptor,NULL,NULL,&tv);
758  int numbytes = 0;
759  if(value == -1){
760  if(verboseMode)
761  vpERROR_TRACE( "Select error" );
762  return -1;
763  }
764  else if(value == 0){
765  //Timeout
766  return 0;
767  }
768  else{
769  if(FD_ISSET((unsigned int)receptor_list[receptorEmitting].socketFileDescriptorReceptor,&readFileDescriptor)){
770  char *buf = new char [max_size_message];
771 #ifdef UNIX
772  numbytes=recv(receptor_list[receptorEmitting].socketFileDescriptorReceptor, buf, max_size_message, 0);
773 #else
774  numbytes=recv((unsigned int)receptor_list[receptorEmitting].socketFileDescriptorReceptor, buf, (int)max_size_message, 0);
775 #endif
776  if(numbytes <= 0)
777  {
778  std::cout << "Disconnected : " << inet_ntoa(receptor_list[receptorEmitting].receptorAddress.sin_addr) << std::endl;
779  receptor_list.erase(receptor_list.begin()+(int)receptorEmitting);
780  return numbytes;
781  }
782  else if(numbytes > 0){
783  std::string returnVal(buf, (unsigned int)numbytes);
784  currentMessageReceived.append(returnVal);
785  }
786  delete [] buf;
787  }
788  }
789 
790  return numbytes;
791 }
792 
793 
794 
unsigned int max_size_message
Definition: vpNetwork.h:124
int receiveRequestOnce()
Definition: vpNetwork.cpp:333
std::string separator
Definition: vpNetwork.h:125
int receiveRequestOnceFrom(const unsigned int &receptorEmitting)
Definition: vpNetwork.cpp:359
std::string beginning
Definition: vpNetwork.h:126
This the request that will transit on the network.
Definition: vpRequest.h:134
std::vector< vpRequest * > request_list
Definition: vpNetwork.h:122
fd_set readFileDescriptor
Definition: vpNetwork.h:114
#define vpERROR_TRACE
Definition: vpDebug.h:379
#define vpTRACE
Definition: vpDebug.h:401
void print(const char *id="")
Definition: vpNetwork.cpp:125
int receiveAndDecodeRequestOnceFrom(const unsigned int &receptorEmitting)
Definition: vpNetwork.cpp:464
int sendRequestTo(vpRequest &req, const unsigned int &dest)
Definition: vpNetwork.cpp:195
std::vector< int > receiveRequestFrom(const unsigned int &receptorEmitting)
Definition: vpNetwork.cpp:309
std::vector< int > receiveAndDecodeRequestFrom(const unsigned int &receptorEmitting)
Definition: vpNetwork.cpp:405
virtual void encode()=0
int socketMax
Definition: vpNetwork.h:116
virtual ~vpNetwork()
Definition: vpNetwork.cpp:67
std::vector< int > receiveAndDecodeRequest()
Definition: vpNetwork.cpp:379
std::string end
Definition: vpNetwork.h:127
int sendAndEncodeRequestTo(vpRequest &req, const unsigned int &dest)
Definition: vpNetwork.cpp:267
unsigned int size()
Definition: vpRequest.h:206
int receiveAndDecodeRequestOnce()
Definition: vpNetwork.cpp:434
int sendAndEncodeRequest(vpRequest &req)
Definition: vpNetwork.cpp:247
long tv_sec
Definition: vpNetwork.h:133
bool verboseMode
Definition: vpNetwork.h:136
std::vector< int > receiveRequest()
Definition: vpNetwork.cpp:287
std::string getId()
Definition: vpRequest.h:190
struct timeval tv
Definition: vpNetwork.h:132
std::vector< vpReceptor > receptor_list
Definition: vpNetwork.h:113
int sendRequest(vpRequest &req)
Definition: vpNetwork.cpp:176
long tv_usec
Definition: vpNetwork.h:134
void removeDecodingRequest(const char *)
Definition: vpNetwork.cpp:108
std::string currentMessageReceived
Definition: vpNetwork.h:130
int getReceptorIndex(const char *name)
Definition: vpNetwork.cpp:140
void addDecodingRequest(vpRequest *)
Definition: vpNetwork.cpp:85
std::string param_sep
Definition: vpNetwork.h:128