ViSP  2.6.2
vpNetwork.cpp
1 /****************************************************************************
2  *
3  * $Id: vpNetwork.cpp 3842 2012-07-13 22:21:42Z fspindle $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2012 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 #include <visp/vpNetwork.h>
43 
45 {
46  separator = "[*@*]";
47  beginning = "[*start*]";
48  end = "[*end*]";
49  param_sep = "[*|*]";
50  max_size_message = 999999;
51 
52  tv_sec = 0;
53  tv_usec = 10;
54 
55  verboseMode = false;
56 
57 #ifdef WIN32
58  //Enable the sockets to be used
59  //Note that: if we were using "winsock.h" instead of "winsock2.h" we would had to use:
60  //WSAStartup(MAKEWORD(1,0), &WSAData);
61  WSADATA WSAData;
62  WSAStartup(MAKEWORD(2,0), &WSAData);
63 #endif
64 }
65 
67 {
68 #ifdef WIN32
69  WSACleanup();
70 #endif
71 }
72 
85 {
86  bool alreadyHas = false;
87 
88  for(unsigned int i = 0 ; i < request_list.size() ; i++)
89  if(request_list[i]->getId() == req->getId()){
90  alreadyHas = true;
91  break;
92  }
93 
94  if(alreadyHas)
95  std::cout << "Server already has one request with the similar ID. Request hasn't been added." << std::endl;
96  else
97  request_list.push_back(req);
98 }
99 
108 {
109  for(unsigned int i = 0 ; i < request_list.size() ; i++)
110  {
111  if(request_list[i]->getId() == id)
112  {
113  request_list.erase(request_list.begin()+i);
114  break;
115  }
116  }
117 }
118 
124 void vpNetwork::print(const char *id)
125 {
126  for(unsigned int i = 0 ; i < receptor_list.size() ; i++)
127  {
128  std::cout << id << i << " : " << inet_ntoa(receptor_list[i].receptorAddress.sin_addr) << std::endl;
129  }
130 }
131 
139 int vpNetwork::getReceptorIndex(const char *name)
140 {
141  struct hostent *server = gethostbyname(name);
142 
143  if ( server == NULL )
144  {
145  std::string noSuchHostMessage( "ERROR, " );
146  noSuchHostMessage.append( name );
147  noSuchHostMessage.append( ": no such host\n" );
148  vpERROR_TRACE( noSuchHostMessage.c_str(), "vpClient::getReceptorIndex()" );
149  }
150 
151  std::string ip = inet_ntoa(*(in_addr *)server->h_addr);
152 
153  for(unsigned int i = 0 ; i < receptor_list.size() ; i++)
154  {
155  if(receptor_list[i].receptorIP == ip)
156  return i;
157  }
158 
159  return -1;
160 }
161 
176 {
177  return sendRequestTo(req,0);
178 }
179 
194 int vpNetwork::sendRequestTo(vpRequest &req, const int &dest)
195 {
196  if(receptor_list.size() == 0 || dest > (int)receptor_list.size()-1)
197  {
198  if(verboseMode)
199  vpTRACE( "Cannot Send Request! Bad Index" );
200  return 0;
201  }
202 
203  std::string message = beginning + req.getId() + separator;
204 
205  if(req.size() != 0){
206  message += req[0];
207 
208  for(unsigned int i = 1 ; i < req.size() ; i++){
209  message += param_sep + req[i];
210  }
211  }
212 
213  message += end;
214 
215  int flags = 0;
216 #if ! defined(APPLE) && ! defined(WIN32)
217  flags = MSG_NOSIGNAL; // Only for Linux
218 #endif
219 
220  int value = sendto(receptor_list[dest].socketFileDescriptorReceptor, message.c_str(), message.size(), flags,
221  (sockaddr*) &receptor_list[dest].receptorAddress,receptor_list[dest].receptorAddressSize);
222 
223  return value;
224 }
225 
240 {
241  req.encode();
242  return sendRequest(req);
243 }
244 
260 {
261  req.encode();
262  return sendRequestTo(req,dest);
263 }
264 
279 std::vector<int> vpNetwork::receiveRequest()
280 {
281  _receiveRequest();
282  return _handleRequests();
283 }
284 
301 std::vector<int> vpNetwork::receiveRequestFrom(const int &receptorEmitting)
302 {
303  _receiveRequestFrom(receptorEmitting);
304  return _handleRequests();
305 }
306 
326 {
327  _receiveRequestOnce();
328  return _handleFirstRequest();
329 }
330 
351 int vpNetwork::receiveRequestOnceFrom(const int &receptorEmitting)
352 {
353  _receiveRequestOnceFrom(receptorEmitting);
354  return _handleFirstRequest();
355 }
356 
372 {
373  std::vector<int> res = receiveRequest();
374  for(unsigned int i = 0 ; i < res.size() ; i++)
375  if(res[i] != -1)
376  request_list[res[i]]->decode();
377 
378  return res;
379 }
380 
397 std::vector<int> vpNetwork::receiveAndDecodeRequestFrom(const int &receptorEmitting)
398 {
399  std::vector<int> res = receiveRequestFrom(receptorEmitting);
400  for(unsigned int i = 0 ; i < res.size() ; i++)
401  if(res[i] != -1)
402  request_list[res[i]]->decode();
403 
404  return res;
405 }
406 
427 {
428  int res = receiveRequestOnce();
429  if(res != -1)
430  request_list[res]->decode();
431 
432  return res;
433 }
434 
456 int vpNetwork::receiveAndDecodeRequestOnceFrom(const int &receptorEmitting)
457 {
458  int res = receiveRequestOnceFrom(receptorEmitting);
459  if(res != -1)
460  request_list[res]->decode();
461 
462  return res;
463 }
464 
465 
466 //######## Definition of Template Functions ########
467 //# #
468 //##################################################
469 
470 
481 std::vector<int> vpNetwork::_handleRequests()
482 {
483  std::vector<int> resIndex;
484  int index = _handleFirstRequest();
485 
486  while(index != -1)
487  {
488  resIndex.push_back(index);
489  index = _handleFirstRequest();
490  }
491 
492  return resIndex;
493 }
494 
505 int vpNetwork::_handleFirstRequest()
506 {
507  int indStart = currentMessageReceived.find(beginning);
508  int indSep = currentMessageReceived.find(separator);
509  int indEnd = currentMessageReceived.find(end);
510 
511  if (indStart == -1 && indSep == -1 && indEnd == -1)
512  {
513  if(currentMessageReceived.size() != 0)
514  currentMessageReceived.clear();
515 
516  if(verboseMode)
517  vpTRACE("Incorrect message");
518 
519  return -1;
520  }
521 
522  if(indStart == -1 || indSep == -1 || indEnd == -1)
523  return -1;
524 
525  if(indEnd < indStart)
526  {
527  if(verboseMode)
528  vpTRACE("Incorrect message");
529  currentMessageReceived.erase(indStart,indEnd+end.size());
530  return -1;
531  }
532 
533  int indStart2 = currentMessageReceived.find(beginning,indStart+1);
534  if(indStart2 != -1 && indStart2 < indEnd)
535  {
536  if(verboseMode)
537  vpTRACE("Incorrect message");
538  currentMessageReceived.erase(indStart,indStart2);
539  return -1;
540  }
541 
542  int deb = indStart + beginning.size();
543  std::string id = currentMessageReceived.substr(deb, indSep - deb);
544 
545  deb = indSep+separator.size();
546  std::string params = currentMessageReceived.substr(deb, indEnd - deb);
547 
548 // std::cout << "Handling : " << currentMessageReceived.substr(indStart, indEnd+end.size() - indStart) << std::endl;
549 
550  int indRequest;
551  bool hasBeenFound = false;
552  for(unsigned int i = 0 ; i < request_list.size() ; i++)
553  {
554  if(id == request_list[i]->getId()){
555  hasBeenFound = true;
556  request_list[i]->clear();
557  indRequest = i;
558  break;
559  }
560  }
561 
562  if(!hasBeenFound){
563  //currentMessageReceived.erase(indStart,indEnd+end.size());
564  if(verboseMode)
565  vpTRACE("No request corresponds to the received message");
566  return -1;
567  }
568 
569  int indDebParam = indSep + separator.size();
570  int indEndParam = currentMessageReceived.find(param_sep,indDebParam);
571 
572  std::string param;
573  while(indEndParam != -1)
574  {
575  param = currentMessageReceived.substr(indDebParam, indEndParam - indDebParam);
576  request_list[indRequest]->addParameter(param);
577  indDebParam = indEndParam+param_sep.size();
578  indEndParam = currentMessageReceived.find(param_sep,indDebParam);
579  }
580 
581  param = currentMessageReceived.substr(indDebParam, indEnd - indDebParam);
582  request_list[indRequest]->addParameter(param);
583  currentMessageReceived.erase(indStart,indEnd+end.size());
584 
585  return indRequest;
586 }
587 
602 void vpNetwork::_receiveRequest()
603 {
604  while(_receiveRequestOnce() > 0) {};
605 }
606 
623 void vpNetwork::_receiveRequestFrom(const int &receptorEmitting)
624 {
625  while(_receiveRequestOnceFrom(receptorEmitting) > 0) {};
626 }
627 
646 int vpNetwork::_receiveRequestOnce()
647 {
648  if(receptor_list.size() == 0)
649  {
650  if(verboseMode)
651  vpTRACE( "No Receptor!" );
652  return -1;
653  }
654 
655  tv.tv_sec = tv_sec;
656  tv.tv_usec = tv_usec;
657 
658  FD_ZERO(&readFileDescriptor);
659 
660  for(unsigned int i=0; i<receptor_list.size(); i++){
661  if(i == 0)
662  socketMax = receptor_list[i].socketFileDescriptorReceptor;
663 
664  FD_SET(receptor_list[i].socketFileDescriptorReceptor,&readFileDescriptor);
665  if(socketMax < receptor_list[i].socketFileDescriptorReceptor) socketMax = receptor_list[i].socketFileDescriptorReceptor;
666  }
667 
668  int value = select(socketMax+1,&readFileDescriptor,NULL,NULL,&tv);
669  int numbytes = 0;
670 
671  if(value == -1){
672  if(verboseMode)
673  vpERROR_TRACE( "Select error" );
674  return -1;
675  }
676  else if(value == 0){
677  //Timeout
678  return 0;
679  }
680  else{
681  for(unsigned int i=0; i<receptor_list.size(); i++){
682  if(FD_ISSET(receptor_list[i].socketFileDescriptorReceptor,&readFileDescriptor)){
683  char *buf = new char [max_size_message];
684  numbytes=recv(receptor_list[i].socketFileDescriptorReceptor, buf, max_size_message, 0);
685 
686  if(numbytes <= 0)
687  {
688  std::cout << "Disconnected : " << inet_ntoa(receptor_list[i].receptorAddress.sin_addr) << std::endl;
689  receptor_list.erase(receptor_list.begin()+i);
690  return numbytes;
691  }
692  else if(numbytes > 0){
693  std::string returnVal(buf, numbytes);
694  currentMessageReceived.append(returnVal);
695  }
696  delete [] buf;
697  break;
698  }
699  }
700  }
701 
702  return numbytes;
703 }
704 
725 int vpNetwork::_receiveRequestOnceFrom(const int &receptorEmitting)
726 {
727  if(receptor_list.size() == 0 || receptorEmitting > (int)receptor_list.size()-1 )
728  {
729  if(verboseMode)
730  vpTRACE( "No receptor at the specified index!" );
731  return -1;
732  }
733 
734  tv.tv_sec = tv_sec;
735  tv.tv_usec = tv_usec;
736 
737  FD_ZERO(&readFileDescriptor);
738 
739  socketMax = receptor_list[receptorEmitting].socketFileDescriptorReceptor;
740  FD_SET(receptor_list[receptorEmitting].socketFileDescriptorReceptor,&readFileDescriptor);
741 
742  int value = select(socketMax+1,&readFileDescriptor,NULL,NULL,&tv);
743  int numbytes = 0;
744  if(value == -1){
745  if(verboseMode)
746  vpERROR_TRACE( "Select error" );
747  return -1;
748  }
749  else if(value == 0){
750  //Timeout
751  return 0;
752  }
753  else{
754  if(FD_ISSET(receptor_list[receptorEmitting].socketFileDescriptorReceptor,&readFileDescriptor)){
755  char *buf = new char [max_size_message];
756  numbytes=recv(receptor_list[receptorEmitting].socketFileDescriptorReceptor, buf, max_size_message, 0);
757 
758  if(numbytes <= 0)
759  {
760  std::cout << "Disconnected : " << inet_ntoa(receptor_list[receptorEmitting].receptorAddress.sin_addr) << std::endl;
761  receptor_list.erase(receptor_list.begin()+receptorEmitting);
762  return numbytes;
763  }
764  else if(numbytes > 0){
765  std::string returnVal(buf, numbytes);
766  currentMessageReceived.append(returnVal);
767  }
768  delete [] buf;
769  }
770  }
771 
772  return numbytes;
773 }
774 
775 
776 
777 
778 
779 
780 
unsigned int max_size_message
Definition: vpNetwork.h:115
int receiveRequestOnce()
Definition: vpNetwork.cpp:325
std::string separator
Definition: vpNetwork.h:116
std::string beginning
Definition: vpNetwork.h:117
This the request that will transit on the network.
Definition: vpRequest.h:134
std::vector< vpRequest * > request_list
Definition: vpNetwork.h:113
fd_set readFileDescriptor
Definition: vpNetwork.h:109
#define vpERROR_TRACE
Definition: vpDebug.h:379
#define vpTRACE
Definition: vpDebug.h:401
virtual void print(const char *id="")
Definition: vpNetwork.cpp:124
virtual void encode()=0
std::vector< int > receiveAndDecodeRequestFrom(const int &receptorEmitting)
Definition: vpNetwork.cpp:397
int socketMax
Definition: vpNetwork.h:110
int receiveRequestOnceFrom(const int &receptorEmitting)
Definition: vpNetwork.cpp:351
virtual ~vpNetwork()
Definition: vpNetwork.cpp:66
std::vector< int > receiveAndDecodeRequest()
Definition: vpNetwork.cpp:371
std::string end
Definition: vpNetwork.h:118
int sendAndEncodeRequestTo(vpRequest &req, const int &dest)
Definition: vpNetwork.cpp:259
std::vector< int > receiveRequestFrom(const int &receptorEmitting)
Definition: vpNetwork.cpp:301
int sendRequestTo(vpRequest &req, const int &dest)
Definition: vpNetwork.cpp:194
unsigned int size()
Definition: vpRequest.h:206
int receiveAndDecodeRequestOnce()
Definition: vpNetwork.cpp:426
int sendAndEncodeRequest(vpRequest &req)
Definition: vpNetwork.cpp:239
long tv_sec
Definition: vpNetwork.h:124
bool verboseMode
Definition: vpNetwork.h:127
std::vector< int > receiveRequest()
Definition: vpNetwork.cpp:279
std::string getId()
Definition: vpRequest.h:190
struct timeval tv
Definition: vpNetwork.h:123
std::vector< vpReceptor > receptor_list
Definition: vpNetwork.h:108
int sendRequest(vpRequest &req)
Definition: vpNetwork.cpp:175
long tv_usec
Definition: vpNetwork.h:125
void removeDecodingRequest(const char *)
Definition: vpNetwork.cpp:107
std::string currentMessageReceived
Definition: vpNetwork.h:121
int getReceptorIndex(const char *name)
Definition: vpNetwork.cpp:139
void addDecodingRequest(vpRequest *)
Definition: vpNetwork.cpp:84
std::string param_sep
Definition: vpNetwork.h:119
int receiveAndDecodeRequestOnceFrom(const int &receptorEmitting)
Definition: vpNetwork.cpp:456