ViSP  2.9.0
vpNetwork.cpp
1 /****************************************************************************
2  *
3  * $Id: vpNetwork.cpp 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 
43 #include <visp/vpNetwork.h>
44 
46  : emitter(), receptor_list(), readFileDescriptor(), socketMax(0), request_list(),
47  max_size_message(999999), separator("[*@*]"), beginning("[*start*]"), end("[*end*]"),
48  param_sep("[*|*]"), currentMessageReceived(), tv(), tv_sec(0), tv_usec(10),
49  verboseMode(false)
50 {
51  tv.tv_sec = tv_sec;
52  tv.tv_usec = tv_usec;
53 
54 #if defined(_WIN32)
55  //Enable the sockets to be used
56  //Note that: if we were using "winsock.h" instead of "winsock2.h" we would had to use:
57  //WSAStartup(MAKEWORD(1,0), &WSAData);
58  WSADATA WSAData;
59  WSAStartup(MAKEWORD(2,0), &WSAData);
60 #endif
61 }
62 
64 {
65 #if defined(_WIN32)
66  WSACleanup();
67 #endif
68 }
69 
82 {
83  bool alreadyHas = false;
84 
85  for(unsigned int i = 0 ; i < request_list.size() ; i++)
86  if(request_list[i]->getId() == req->getId()){
87  alreadyHas = true;
88  break;
89  }
90 
91  if(alreadyHas)
92  std::cout << "Server already has one request with the similar ID. Request hasn't been added." << std::endl;
93  else
94  request_list.push_back(req);
95 }
96 
105 {
106  for(unsigned int i = 0 ; i < request_list.size() ; i++)
107  {
108  if(request_list[i]->getId() == id)
109  {
110  request_list.erase(request_list.begin()+(int)i);
111  break;
112  }
113  }
114 }
115 
121 void vpNetwork::print(const char *id)
122 {
123  for(unsigned int i = 0 ; i < receptor_list.size() ; i++)
124  {
125  std::cout << id << i << " : " << inet_ntoa(receptor_list[i].receptorAddress.sin_addr) << std::endl;
126  }
127 }
128 
136 int vpNetwork::getReceptorIndex(const char *name)
137 {
138  struct hostent *server = gethostbyname(name);
139 
140  if ( server == NULL )
141  {
142  std::string noSuchHostMessage( "ERROR, " );
143  noSuchHostMessage.append( name );
144  noSuchHostMessage.append( ": no such host\n" );
145  vpERROR_TRACE( noSuchHostMessage.c_str(), "vpNetwork::getReceptorIndex()" );
146  return -1;
147  }
148 
149  std::string ip = inet_ntoa(*(in_addr *)server->h_addr);
150 
151  for(int i = 0 ; i < (int)receptor_list.size() ; i++)
152  {
153  if(receptor_list[(unsigned)i].receptorIP == ip)
154  return i;
155  }
156 
157  return -1;
158 }
159 
174 {
175  return sendRequestTo(req,0);
176 }
177 
192 int vpNetwork::sendRequestTo(vpRequest &req, const unsigned int &dest)
193 {
194  int size = (int)receptor_list.size();
195  int sizeMinusOne = (int)receptor_list.size()-1;
196  if(size == 0 || dest > (unsigned)sizeMinusOne)
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(SOLARIS) && ! defined(_WIN32)
217 #if defined(__linux__)
218  flags = MSG_NOSIGNAL; // Only for Linux
219 #endif
220 
221 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
222  int value = sendto(receptor_list[dest].socketFileDescriptorReceptor, message.c_str(), message.size(), flags,
223  (sockaddr*) &receptor_list[dest].receptorAddress,receptor_list[dest].receptorAddressSize);
224 #else
225  int value = sendto((unsigned)receptor_list[dest].socketFileDescriptorReceptor, message.c_str(), (int)message.size(), flags,
226  (sockaddr*) &receptor_list[dest].receptorAddress,receptor_list[dest].receptorAddressSize);
227 #endif
228 
229  return value;
230 }
231 
246 {
247  req.encode();
248  return sendRequest(req);
249 }
250 
265 int vpNetwork::sendAndEncodeRequestTo(vpRequest &req, const unsigned int &dest)
266 {
267  req.encode();
268  return sendRequestTo(req,dest);
269 }
270 
285 std::vector<int> vpNetwork::receiveRequest()
286 {
287  _receiveRequest();
288  return _handleRequests();
289 }
290 
307 std::vector<int> vpNetwork::receiveRequestFrom(const unsigned int &receptorEmitting)
308 {
309  _receiveRequestFrom(receptorEmitting);
310  return _handleRequests();
311 }
312 
332 {
333  _receiveRequestOnce();
334  return _handleFirstRequest();
335 }
336 
357 int vpNetwork::receiveRequestOnceFrom(const unsigned int &receptorEmitting)
358 {
359  _receiveRequestOnceFrom(receptorEmitting);
360  return _handleFirstRequest();
361 }
362 
378 {
379  std::vector<int> res = receiveRequest();
380  for(unsigned int i = 0 ; i < res.size() ; i++)
381  if(res[i] != -1)
382  request_list[(unsigned)res[i]]->decode();
383 
384  return res;
385 }
386 
403 std::vector<int> vpNetwork::receiveAndDecodeRequestFrom(const unsigned int &receptorEmitting)
404 {
405  std::vector<int> res = receiveRequestFrom(receptorEmitting);
406  for(unsigned int i = 0 ; i < res.size() ; i++)
407  if(res[i] != -1)
408  request_list[(unsigned)res[i]]->decode();
409 
410  return res;
411 }
412 
433 {
434  int res = receiveRequestOnce();
435  if(res != -1)
436  request_list[(unsigned)res]->decode();
437 
438  return res;
439 }
440 
462 int vpNetwork::receiveAndDecodeRequestOnceFrom(const unsigned int &receptorEmitting)
463 {
464  int res = receiveRequestOnceFrom(receptorEmitting);
465  if(res != -1)
466  request_list[(unsigned)res]->decode();
467 
468  return res;
469 }
470 
471 
472 //######## Definition of Template Functions ########
473 //# #
474 //##################################################
475 
476 
487 std::vector<int> vpNetwork::_handleRequests()
488 {
489  std::vector<int> resIndex;
490  int index = _handleFirstRequest();
491 
492  while(index != -1)
493  {
494  resIndex.push_back(index);
495  index = _handleFirstRequest();
496  }
497 
498  return resIndex;
499 }
500 
511 int vpNetwork::_handleFirstRequest()
512 {
513  size_t indStart = currentMessageReceived.find(beginning);
514  size_t indSep = currentMessageReceived.find(separator);
515  size_t indEnd = currentMessageReceived.find(end);
516 
517  if (indStart == std::string::npos && indSep == std::string::npos && indEnd == std::string::npos)
518  {
519  if(currentMessageReceived.size() != 0)
520  currentMessageReceived.clear();
521 
522  if(verboseMode)
523  vpTRACE("Incorrect message");
524 
525  return -1;
526  }
527 
528  if(indStart == std::string::npos || indSep == std::string::npos || indEnd == std::string::npos)
529  return -1;
530 
531  if(indEnd < indStart)
532  {
533  if(verboseMode)
534  vpTRACE("Incorrect message");
535  currentMessageReceived.erase((unsigned)indStart,indEnd+end.size());
536  return -1;
537  }
538 
539  size_t indStart2 = currentMessageReceived.find(beginning,indStart+1);
540  if(indStart2 != std::string::npos && indStart2 < indEnd)
541  {
542  if(verboseMode)
543  vpTRACE("Incorrect message");
544  currentMessageReceived.erase((unsigned)indStart,(unsigned)indStart2);
545  return -1;
546  }
547 
548  size_t deb = indStart + beginning.size();
549  std::string id = currentMessageReceived.substr((unsigned)deb, indSep - deb);
550 
551  deb = indSep+separator.size();
552  std::string params = currentMessageReceived.substr((unsigned)deb, (unsigned)(indEnd - deb));
553 
554 // std::cout << "Handling : " << currentMessageReceived.substr(indStart, indEnd+end.size() - indStart) << std::endl;
555 
556  int indRequest = 0;
557  bool hasBeenFound = false;
558  for(unsigned int i = 0 ; i < request_list.size() ; i++)
559  {
560  if(id == request_list[i]->getId()){
561  hasBeenFound = true;
562  request_list[i]->clear();
563  indRequest = (int)i;
564  break;
565  }
566  }
567 
568  if(!hasBeenFound){
569  //currentMessageReceived.erase(indStart,indEnd+end.size());
570  if(verboseMode)
571  vpTRACE("No request corresponds to the received message");
572  return -1;
573  }
574 
575  size_t indDebParam = indSep + separator.size();
576  size_t indEndParam = currentMessageReceived.find(param_sep,indDebParam);
577 
578  std::string param;
579  while(indEndParam != std::string::npos)
580  {
581  param = currentMessageReceived.substr((unsigned)indDebParam,(unsigned)(indEndParam - indDebParam));
582  request_list[(unsigned)indRequest]->addParameter(param);
583  indDebParam = indEndParam+param_sep.size();
584  indEndParam = currentMessageReceived.find(param_sep,indDebParam);
585  }
586 
587  param = currentMessageReceived.substr((unsigned)indDebParam, indEnd - indDebParam);
588  request_list[(unsigned)indRequest]->addParameter(param);
589  currentMessageReceived.erase(indStart,indEnd+end.size());
590 
591  return indRequest;
592 }
593 
608 void vpNetwork::_receiveRequest()
609 {
610  while(_receiveRequestOnce() > 0) {};
611 }
612 
629 void vpNetwork::_receiveRequestFrom(const unsigned int &receptorEmitting)
630 {
631  while(_receiveRequestOnceFrom(receptorEmitting) > 0) {};
632 }
633 
652 int vpNetwork::_receiveRequestOnce()
653 {
654  if(receptor_list.size() == 0)
655  {
656  if(verboseMode)
657  vpTRACE( "No Receptor!" );
658  return -1;
659  }
660 
661  tv.tv_sec = tv_sec;
662  tv.tv_usec = tv_usec;
663 
664  FD_ZERO(&readFileDescriptor);
665 
666  for(unsigned int i=0; i<receptor_list.size(); i++){
667  if(i == 0)
668  socketMax = receptor_list[i].socketFileDescriptorReceptor;
669 
670  FD_SET((unsigned)receptor_list[i].socketFileDescriptorReceptor,&readFileDescriptor);
671  if(socketMax < receptor_list[i].socketFileDescriptorReceptor) socketMax = receptor_list[i].socketFileDescriptorReceptor;
672  }
673 
674  int value = select((int)socketMax+1,&readFileDescriptor,NULL,NULL,&tv);
675  int numbytes = 0;
676 
677  if(value == -1){
678  if(verboseMode)
679  vpERROR_TRACE( "Select error" );
680  return -1;
681  }
682  else if(value == 0){
683  //Timeout
684  return 0;
685  }
686  else{
687  for(unsigned int i=0; i<receptor_list.size(); i++){
688  if(FD_ISSET((unsigned int)receptor_list[i].socketFileDescriptorReceptor,&readFileDescriptor)){
689  char *buf = new char [max_size_message];
690 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
691  numbytes=recv(receptor_list[i].socketFileDescriptorReceptor, buf, max_size_message, 0);
692 #else
693  numbytes=recv((unsigned int)receptor_list[i].socketFileDescriptorReceptor, buf, (int)max_size_message, 0);
694 #endif
695 
696  if(numbytes <= 0)
697  {
698  std::cout << "Disconnected : " << inet_ntoa(receptor_list[i].receptorAddress.sin_addr) << std::endl;
699  receptor_list.erase(receptor_list.begin()+(int)i);
700  delete [] buf;
701  return numbytes;
702  }
703  else if(numbytes > 0){
704  std::string returnVal(buf, (unsigned int)numbytes);
705  currentMessageReceived.append(returnVal);
706  }
707  delete [] buf;
708  break;
709  }
710  }
711  }
712 
713  return numbytes;
714 }
715 
736 int vpNetwork::_receiveRequestOnceFrom(const unsigned int &receptorEmitting)
737 {
738  int size = (int)receptor_list.size();
739  int sizeMinusOne = (int)receptor_list.size()-1;
740  if(size == 0 || receptorEmitting > (unsigned)sizeMinusOne )
741  {
742  if(verboseMode)
743  vpTRACE( "No receptor at the specified index!" );
744  return -1;
745  }
746 
747  tv.tv_sec = tv_sec;
748  tv.tv_usec = tv_usec;
749 
750  FD_ZERO(&readFileDescriptor);
751 
752  socketMax = receptor_list[receptorEmitting].socketFileDescriptorReceptor;
753  FD_SET((unsigned int)receptor_list[receptorEmitting].socketFileDescriptorReceptor,&readFileDescriptor);
754 
755  int value = select((int)socketMax+1,&readFileDescriptor,NULL,NULL,&tv);
756  int numbytes = 0;
757  if(value == -1){
758  if(verboseMode)
759  vpERROR_TRACE( "Select error" );
760  return -1;
761  }
762  else if(value == 0){
763  //Timeout
764  return 0;
765  }
766  else{
767  if(FD_ISSET((unsigned int)receptor_list[receptorEmitting].socketFileDescriptorReceptor,&readFileDescriptor)){
768  char *buf = new char [max_size_message];
769 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
770  numbytes=recv(receptor_list[receptorEmitting].socketFileDescriptorReceptor, buf, max_size_message, 0);
771 #else
772  numbytes=recv((unsigned int)receptor_list[receptorEmitting].socketFileDescriptorReceptor, buf, (int)max_size_message, 0);
773 #endif
774  if(numbytes <= 0)
775  {
776  std::cout << "Disconnected : " << inet_ntoa(receptor_list[receptorEmitting].receptorAddress.sin_addr) << std::endl;
777  receptor_list.erase(receptor_list.begin()+(int)receptorEmitting);
778  delete [] buf;
779  return numbytes;
780  }
781  else if(numbytes > 0){
782  std::string returnVal(buf, (unsigned int)numbytes);
783  currentMessageReceived.append(returnVal);
784  }
785  delete [] buf;
786  }
787  }
788 
789  return numbytes;
790 }
791 
792 
793 
unsigned int max_size_message
Definition: vpNetwork.h:133
int receiveRequestOnce()
Definition: vpNetwork.cpp:331
std::string separator
Definition: vpNetwork.h:134
int receiveRequestOnceFrom(const unsigned int &receptorEmitting)
Definition: vpNetwork.cpp:357
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
fd_set readFileDescriptor
Definition: vpNetwork.h:123
#define vpERROR_TRACE
Definition: vpDebug.h:395
#define vpTRACE
Definition: vpDebug.h:418
void print(const char *id="")
Definition: vpNetwork.cpp:121
int receiveAndDecodeRequestOnceFrom(const unsigned int &receptorEmitting)
Definition: vpNetwork.cpp:462
int sendRequestTo(vpRequest &req, const unsigned int &dest)
Definition: vpNetwork.cpp:192
std::vector< int > receiveRequestFrom(const unsigned int &receptorEmitting)
Definition: vpNetwork.cpp:307
std::vector< int > receiveAndDecodeRequestFrom(const unsigned int &receptorEmitting)
Definition: vpNetwork.cpp:403
virtual void encode()=0
SOCKET socketMax
Definition: vpNetwork.h:127
virtual ~vpNetwork()
Definition: vpNetwork.cpp:63
std::vector< int > receiveAndDecodeRequest()
Definition: vpNetwork.cpp:377
std::string end
Definition: vpNetwork.h:136
int sendAndEncodeRequestTo(vpRequest &req, const unsigned int &dest)
Definition: vpNetwork.cpp:265
unsigned int size()
Definition: vpRequest.h:206
int receiveAndDecodeRequestOnce()
Definition: vpNetwork.cpp:432
int sendAndEncodeRequest(vpRequest &req)
Definition: vpNetwork.cpp:245
long tv_sec
Definition: vpNetwork.h:142
bool verboseMode
Definition: vpNetwork.h:145
std::vector< int > receiveRequest()
Definition: vpNetwork.cpp:285
std::string getId()
Definition: vpRequest.h:190
struct timeval tv
Definition: vpNetwork.h:141
std::vector< vpReceptor > receptor_list
Definition: vpNetwork.h:122
int sendRequest(vpRequest &req)
Definition: vpNetwork.cpp:173
long tv_usec
Definition: vpNetwork.h:143
void removeDecodingRequest(const char *)
Definition: vpNetwork.cpp:104
std::string currentMessageReceived
Definition: vpNetwork.h:139
int getReceptorIndex(const char *name)
Definition: vpNetwork.cpp:136
void addDecodingRequest(vpRequest *)
Definition: vpNetwork.cpp:81
std::string param_sep
Definition: vpNetwork.h:137