1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2019 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See http://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * TCP Network
33  *
34  * Authors:
35  * Aurelien Yol
36  *
37  *****************************************************************************/
38 
39 #include <visp3/core/vpNetwork.h>
40 
41 // inet_ntop() not supported on win XP
42 #ifdef VISP_HAVE_FUNC_INET_NTOP
43 
vpNetwork()44 vpNetwork::vpNetwork()
45   : emitter(), receptor_list(), readFileDescriptor(), socketMax(0), request_list(), max_size_message(999999),
46     separator("[*@*]"), beginning("[*start*]"), end("[*end*]"), param_sep("[*|*]"), currentMessageReceived(), tv(),
47     tv_sec(0), tv_usec(10), verboseMode(false)
48 {
49   tv.tv_sec = tv_sec;
50 #if TARGET_OS_IPHONE
51   tv.tv_usec = (int)tv_usec;
52 #else
53   tv.tv_usec = tv_usec;
54 #endif
55 
56 #if defined(_WIN32)
57   // Enable the sockets to be used
58   // Note that: if we were using "winsock.h" instead of "winsock2.h" we would
59   // had to use:  WSAStartup(MAKEWORD(1,0), &WSAData);
60   WSADATA WSAData;
61   WSAStartup(MAKEWORD(2, 0), &WSAData);
62 #endif
63 }
64 
~vpNetwork()65 vpNetwork::~vpNetwork()
66 {
67 #if defined(_WIN32)
68   WSACleanup();
69 #endif
70 }
71 
72 /*!
73   Add a decoding request to the emitter. This request will be used to decode
74   the received messages. Each request must have a different id.
75 
76   \warning vpRequest is a virtual pure class. It has to be implemented
77   according to the way how you want to decode the message received.
78 
79   \sa vpNetwork::removeDecodingRequest()
80 
81   \param req : Request to add.
82 */
addDecodingRequest(vpRequest * req)83 void vpNetwork::addDecodingRequest(vpRequest *req)
84 {
85   bool alreadyHas = false;
86 
87   for (unsigned int i = 0; i < request_list.size(); i++)
88     if (request_list[i]->getId() == req->getId()) {
89       alreadyHas = true;
90       break;
91     }
92 
93   if (alreadyHas)
94     std::cout << "Server already has one request with the similar ID. "
95                  "Request hasn't been added."
96               << std::endl;
97   else
98     request_list.push_back(req);
99 }
100 
101 /*!
102   Delete a decoding request from the emitter.
103 
104   \sa vpNetwork::addDecodingRequest()
105 
106   \param id : Id of the request to delete.
107 */
removeDecodingRequest(const char * id)108 void vpNetwork::removeDecodingRequest(const char *id)
109 {
110   for (unsigned int i = 0; i < request_list.size(); i++) {
111     if (request_list[i]->getId() == id) {
112       request_list.erase(request_list.begin() + (int)i);
113       break;
114     }
115   }
116 }
117 
118 /*!
119   Print the receptors.
120 
121   \param id : Message to display before the receptor's index.
122 */
print(const char * id)123 void vpNetwork::print(const char *id)
124 {
125   for (unsigned int i = 0; i < receptor_list.size(); i++) {
126     std::cout << id << i << " : " << inet_ntoa(receptor_list[i].receptorAddress.sin_addr) << std::endl;
127   }
128 }
129 
130 /*!
131   Get the receptor index from its name. The name can be either the IP, or its
132   name on the network.
133 
134   \param name : Name of the receptor.
135 
136   \return Index of the receptor, or -1 if an error occurs.
137 */
getReceptorIndex(const char * name)138 int vpNetwork::getReceptorIndex(const char *name)
139 {
140   struct hostent *server = gethostbyname(name);
141 
142   if (server == NULL) {
143     std::string noSuchHostMessage("ERROR, ");
144     noSuchHostMessage.append(name);
145     noSuchHostMessage.append(": no such host\n");
146     vpERROR_TRACE(noSuchHostMessage.c_str(), "vpNetwork::getReceptorIndex()");
147     return -1;
148   }
149 
150   std::string ip = inet_ntoa(*(in_addr *)server->h_addr);
151 
152   for (int i = 0; i < (int)receptor_list.size(); i++) {
153     if (receptor_list[(unsigned)i].receptorIP == ip)
154       return i;
155   }
156 
157   return -1;
158 }
159 
160 /*!
161   Send a request to the first receptor in the list.
162 
163   \sa vpNetwork::sendRequestTo()
164   \sa vpNetwork::sendAndEncodeRequest()
165   \sa vpNetwork::sendAndEncodeRequestTo()
166   \sa vpNetwork::send()
167   \sa vpNetwork::sendTo()
168 
169   \param req : Request to send.
170 
171   \return The number of bytes that have been sent, -1 if an error occured.
172 */
sendRequest(vpRequest & req)173 int vpNetwork::sendRequest(vpRequest &req) { return sendRequestTo(req, 0); }
174 
175 /*!
176   Send a request to a specific receptor.
177 
178   \sa vpNetwork::sendRequest()
179   \sa vpNetwork::sendAndEncodeRequest()
180   \sa vpNetwork::sendAndEncodeRequestTo()
181   \sa vpNetwork::send()
182   \sa vpNetwork::sendTo()
183 
184   \param req : Request to send.
185   \param dest : Index of the receptor receiving the request.
186 
187   \return The number of bytes that have been sent, -1 if an error occured.
188 */
sendRequestTo(vpRequest & req,const unsigned int & dest)189 int vpNetwork::sendRequestTo(vpRequest &req, const unsigned int &dest)
190 {
191   int size = (int)receptor_list.size();
192   int sizeMinusOne = (int)receptor_list.size() - 1;
193   if (size == 0 || dest > (unsigned)sizeMinusOne) {
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 = (int)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(),
222                      flags, (sockaddr *)&receptor_list[dest].receptorAddress, receptor_list[dest].receptorAddressSize);
223 #endif
224 
225   return value;
226 }
227 
228 /*!
229   Send and encode a request to the first receptor in the list.
230 
231   \sa vpNetwork::sendRequestTo()
232   \sa vpNetwork::sendAndEncodeRequest()
233   \sa vpNetwork::sendAndEncodeRequestTo()
234   \sa vpNetwork::send()
235   \sa vpNetwork::sendTo()
236 
237   \param req : Request to send.
238 
239   \return The number of bytes that have been sent, -1 if an error occured.
240 */
sendAndEncodeRequest(vpRequest & req)241 int vpNetwork::sendAndEncodeRequest(vpRequest &req)
242 {
243   req.encode();
244   return sendRequest(req);
245 }
246 
247 /*!
248   Send and encode a request to a specific receptor.
249 
250   \sa vpNetwork::sendRequest()
251   \sa vpNetwork::sendAndEncodeRequest()
252   \sa vpNetwork::sendAndEncodeRequestTo()
253   \sa vpNetwork::send()
254   \sa vpNetwork::sendTo()
255 
256   \param req : Request to send.
257   \param dest : Index of the receptor receiving the request.
258 
259   \return The number of bytes that have been sent, -1 if an error occured.
260 */
sendAndEncodeRequestTo(vpRequest & req,const unsigned int & dest)261 int vpNetwork::sendAndEncodeRequestTo(vpRequest &req, const unsigned int &dest)
262 {
263   req.encode();
264   return sendRequestTo(req, dest);
265 }
266 
267 /*!
268   Receive requests untils there is requests to receive.
269 
270   \warning Requests will be received but not decoded.
271 
272   \sa vpNetwork::receive()
273   \sa vpNetwork::receiveRequestFrom()
274   \sa vpNetwork::receiveRequestOnce()
275   \sa vpNetwork::receiveRequestOnceFrom()
276   \sa vpNetwork::receiveAndDecodeRequest()
277   \sa vpNetwork::receiveAndDecodeRequestFrom()
278   \sa vpNetwork::receiveAndDecodeRequestOnce()
279   \sa vpNetwork::receiveAndDecodeRequestOnceFrom()
280 */
receiveRequest()281 std::vector<int> vpNetwork::receiveRequest()
282 {
283   _receiveRequest();
284   return _handleRequests();
285 }
286 
287 /*!
288   Receives requests, from a specific emitter, untils there is request to
289   receive.
290 
291   \warning Requests will be received but not decoded.
292 
293   \sa vpNetwork::receive()
294   \sa vpNetwork::receiveRequest()
295   \sa vpNetwork::receiveRequestOnce()
296   \sa vpNetwork::receiveRequestOnceFrom()
297   \sa vpNetwork::receiveAndDecodeRequest()
298   \sa vpNetwork::receiveAndDecodeRequestFrom()
299   \sa vpNetwork::receiveAndDecodeRequestOnce()
300   \sa vpNetwork::receiveAndDecodeRequestOnceFrom()
301 
302   \param receptorEmitting : Index of the receptor emitting the message
303 */
receiveRequestFrom(const unsigned int & receptorEmitting)304 std::vector<int> vpNetwork::receiveRequestFrom(const unsigned int &receptorEmitting)
305 {
306   _receiveRequestFrom(receptorEmitting);
307   return _handleRequests();
308 }
309 
310 /*!
311   Receives a message once (in the limit of the Maximum message size value).
312   This message can represent an entire request or not. Several calls to this
313   function might be necessary to get the entire request.
314 
315   \warning Requests will be received but not decoded.
316 
317   \sa vpNetwork::receive()
318   \sa vpNetwork::receiveRequestFrom()
319   \sa vpNetwork::receiveRequest()
320   \sa vpNetwork::receiveRequestOnceFrom()
321   \sa vpNetwork::receiveAndDecodeRequest()
322   \sa vpNetwork::receiveAndDecodeRequestFrom()
323   \sa vpNetwork::receiveAndDecodeRequestOnce()
324   \sa vpNetwork::receiveAndDecodeRequestOnceFrom()
325 
326   \return The number of bytes received, -1 if an error occured.
327 */
receiveRequestOnce()328 int vpNetwork::receiveRequestOnce()
329 {
330   _receiveRequestOnce();
331   return _handleFirstRequest();
332 }
333 
334 /*!
335   Receives a message once (in the limit of the Maximum message size value),
336   from a specific emitter. This message can represent an entire request or
337   not. Several calls to this function might be necessary to get the entire
338   request.
339 
340   \warning Requests will be received but not decoded.
341 
342   \sa vpNetwork::receive()
343   \sa vpNetwork::receiveRequestFrom()
344   \sa vpNetwork::receiveRequest()
345   \sa vpNetwork::receiveRequestOnce()
346   \sa vpNetwork::receiveAndDecodeRequest()
347   \sa vpNetwork::receiveAndDecodeRequestFrom()
348   \sa vpNetwork::receiveAndDecodeRequestOnce()
349   \sa vpNetwork::receiveAndDecodeRequestOnceFrom()
350 
351   \param receptorEmitting : Index of the receptor emitting the message.
352 
353   \return The number of bytes received, -1 if an error occured.
354 */
receiveRequestOnceFrom(const unsigned int & receptorEmitting)355 int vpNetwork::receiveRequestOnceFrom(const unsigned int &receptorEmitting)
356 {
357   _receiveRequestOnceFrom(receptorEmitting);
358   return _handleFirstRequest();
359 }
360 
361 /*!
362   Receives and decode requests untils there is requests to receive.
363 
364   \warning Requests will be received but not decoded.
365 
366   \sa vpNetwork::receive()
367   \sa vpNetwork::receiveRequestFrom()
368   \sa vpNetwork::receiveRequestOnce()
369   \sa vpNetwork::receiveRequestOnceFrom()
370   \sa vpNetwork::receiveAndDecodeRequest()
371   \sa vpNetwork::receiveAndDecodeRequestFrom()
372   \sa vpNetwork::receiveAndDecodeRequestOnce()
373   \sa vpNetwork::receiveAndDecodeRequestOnceFrom()
374 */
receiveAndDecodeRequest()375 std::vector<int> vpNetwork::receiveAndDecodeRequest()
376 {
377   std::vector<int> res = receiveRequest();
378   for (unsigned int i = 0; i < res.size(); i++)
379     if (res[i] != -1)
380       request_list[(unsigned)res[i]]->decode();
381 
382   return res;
383 }
384 
385 /*!
386   Receives and decode requests, from a specific emitter, untils there is
387   request to receive.
388 
389   \warning Requests will be received but not decoded.
390 
391   \sa vpNetwork::receive()
392   \sa vpNetwork::receiveRequest()
393   \sa vpNetwork::receiveRequestOnce()
394   \sa vpNetwork::receiveRequestOnceFrom()
395   \sa vpNetwork::receiveAndDecodeRequest()
396   \sa vpNetwork::receiveAndDecodeRequestFrom()
397   \sa vpNetwork::receiveAndDecodeRequestOnce()
398   \sa vpNetwork::receiveAndDecodeRequestOnceFrom()
399 
400   \param receptorEmitting : Index of the receptor emitting the message
401 */
receiveAndDecodeRequestFrom(const unsigned int & receptorEmitting)402 std::vector<int> vpNetwork::receiveAndDecodeRequestFrom(const unsigned int &receptorEmitting)
403 {
404   std::vector<int> res = receiveRequestFrom(receptorEmitting);
405   for (unsigned int i = 0; i < res.size(); i++) {
406     if (res[i] != -1)
407       request_list[(unsigned)res[i]]->decode();
408   }
409 
410   return res;
411 }
412 
413 /*!
414   Receives a message once (in the limit of the Maximum message size value).
415   This message can represent an entire request or not. Several calls to this
416   function might be necessary to get the entire request. If it represents an
417   entire request, it decodes the request.
418 
419   \warning Requests will be received but not decoded.
420 
421   \sa vpNetwork::receive()
422   \sa vpNetwork::receiveRequestFrom()
423   \sa vpNetwork::receiveRequest()
424   \sa vpNetwork::receiveRequestOnceFrom()
425   \sa vpNetwork::receiveAndDecodeRequest()
426   \sa vpNetwork::receiveAndDecodeRequestFrom()
427   \sa vpNetwork::receiveAndDecodeRequestOnce()
428   \sa vpNetwork::receiveAndDecodeRequestOnceFrom()
429 
430   \return The number of bytes received, -1 if an error occured.
431 */
receiveAndDecodeRequestOnce()432 int vpNetwork::receiveAndDecodeRequestOnce()
433 {
434   int res = receiveRequestOnce();
435   if (res != -1)
436     request_list[(unsigned)res]->decode();
437 
438   return res;
439 }
440 
441 /*!
442   Receives a message once (in the limit of the Maximum message size value),
443   from a specific emitter. This message can represent an entire request or
444   not. Several calls to this function might be necessary to get the entire
445   request. If it represents an entire request, it decodes the request.
446 
447   \warning Requests will be received but not decoded.
448 
449   \sa vpNetwork::receive()
450   \sa vpNetwork::receiveRequestFrom()
451   \sa vpNetwork::receiveRequest()
452   \sa vpNetwork::receiveRequestOnce()
453   \sa vpNetwork::receiveAndDecodeRequest()
454   \sa vpNetwork::receiveAndDecodeRequestFrom()
455   \sa vpNetwork::receiveAndDecodeRequestOnce()
456   \sa vpNetwork::receiveAndDecodeRequestOnceFrom()
457 
458   \param receptorEmitting : Index of the receptor emitting the message.
459 
460   \return The number of bytes received, -1 if an error occured.
461 */
receiveAndDecodeRequestOnceFrom(const unsigned int & receptorEmitting)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 //######## Definition of Template Functions ########
472 //#                                                #
473 //##################################################
474 
475 /*!
476   Handle requests until there are requests to handle.
477 
478   \warning : This function doesn't decode the requests. If it does handle a
479   request that hasn't been ran yet, The request's parameters will be replace.
480 
481   \sa vpNetwork::handleFirstRequest()
482 
483   \return : The list of index corresponding to the requests that have been
484   handled.
485 */
_handleRequests()486 std::vector<int> vpNetwork::_handleRequests()
487 {
488   std::vector<int> resIndex;
489   int index = _handleFirstRequest();
490 
491   while (index != -1) {
492     resIndex.push_back(index);
493     index = _handleFirstRequest();
494   }
495 
496   return resIndex;
497 }
498 
499 /*!
500   Handle the first request in the queue.
501 
502   \warning : This function doesn't run the request. If it does handle a
503   request that hasn't been ran yet, The request's parameters will be replace.
504 
505   \sa vpNetwork::handleRequests()
506 
507   \return : The index of the request that has been handled.
508 */
_handleFirstRequest()509 int vpNetwork::_handleFirstRequest()
510 {
511   size_t indStart = currentMessageReceived.find(beginning);
512   size_t indSep = currentMessageReceived.find(separator);
513   size_t indEnd = currentMessageReceived.find(end);
514 
515   if (indStart == std::string::npos && indSep == std::string::npos && indEnd == std::string::npos) {
516     if (currentMessageReceived.size() != 0)
517       currentMessageReceived.clear();
518 
519     if (verboseMode)
520       vpTRACE("Incorrect message");
521 
522     return -1;
523   }
524 
525   if (indStart == std::string::npos || indSep == std::string::npos || indEnd == std::string::npos)
526     return -1;
527 
528   if (indEnd < indStart) {
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     if (verboseMode)
538       vpTRACE("Incorrect message");
539     currentMessageReceived.erase((unsigned)indStart, (unsigned)indStart2);
540     return -1;
541   }
542 
543   size_t deb = indStart + beginning.size();
544   std::string id = currentMessageReceived.substr((unsigned)deb, indSep - deb);
545 
546   // deb = indSep+separator.size();
547   // std::string params = currentMessageReceived.substr((unsigned)deb,
548   // (unsigned)(indEnd - deb));
549 
550   //   std::cout << "Handling : " << currentMessageReceived.substr(indStart,
551   //   indEnd+end.size() - indStart) << std::endl;
552 
553   int indRequest = 0;
554   bool hasBeenFound = false;
555   for (unsigned int i = 0; i < request_list.size(); i++) {
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     param = currentMessageReceived.substr((unsigned)indDebParam, (unsigned)(indEndParam - indDebParam));
577     request_list[(unsigned)indRequest]->addParameter(param);
578     indDebParam = indEndParam + param_sep.size();
579     indEndParam = currentMessageReceived.find(param_sep, indDebParam);
580   }
581 
582   param = currentMessageReceived.substr((unsigned)indDebParam, indEnd - indDebParam);
583   request_list[(unsigned)indRequest]->addParameter(param);
584   currentMessageReceived.erase(indStart, indEnd + end.size());
585 
586   return indRequest;
587 }
588 
589 /*!
590   Receive requests untils there is requests to receive.
591 
592   \warning Requests will be received but not decoded.
593 
594   \sa vpNetwork::receive()
595   \sa vpNetwork::receiveRequestFrom()
596   \sa vpNetwork::receiveRequestOnce()
597   \sa vpNetwork::receiveRequestOnceFrom()
598   \sa vpNetwork::receiveAndDecodeRequest()
599   \sa vpNetwork::receiveAndDecodeRequestFrom()
600   \sa vpNetwork::receiveAndDecodeRequestOnce()
601   \sa vpNetwork::receiveAndDecodeRequestOnceFrom()
602 */
_receiveRequest()603 void vpNetwork::_receiveRequest()
604 {
605   while (_receiveRequestOnce() > 0) {
606   };
607 }
608 
609 /*!
610   Receives requests, from a specific emitter, untils there is request to
611   receive.
612 
613   \warning Requests will be received but not decoded.
614 
615   \sa vpNetwork::receive()
616   \sa vpNetwork::receiveRequest()
617   \sa vpNetwork::receiveRequestOnce()
618   \sa vpNetwork::receiveRequestOnceFrom()
619   \sa vpNetwork::receiveAndDecodeRequest()
620   \sa vpNetwork::receiveAndDecodeRequestFrom()
621   \sa vpNetwork::receiveAndDecodeRequestOnce()
622   \sa vpNetwork::receiveAndDecodeRequestOnceFrom()
623 
624   \param receptorEmitting : Index of the receptor emitting the message
625 */
_receiveRequestFrom(const unsigned int & receptorEmitting)626 void vpNetwork::_receiveRequestFrom(const unsigned int &receptorEmitting)
627 {
628   while (_receiveRequestOnceFrom(receptorEmitting) > 0) {
629   };
630 }
631 
632 /*!
633   Receives a message once (in the limit of the Maximum message size value).
634   This message can represent an entire request or not. Several calls to this
635   function might be necessary to get the entire request.
636 
637   \warning Requests will be received but not decoded.
638 
639   \sa vpNetwork::receive()
640   \sa vpNetwork::receiveRequestFrom()
641   \sa vpNetwork::receiveRequest()
642   \sa vpNetwork::receiveRequestOnceFrom()
643   \sa vpNetwork::receiveAndDecodeRequest()
644   \sa vpNetwork::receiveAndDecodeRequestFrom()
645   \sa vpNetwork::receiveAndDecodeRequestOnce()
646   \sa vpNetwork::receiveAndDecodeRequestOnceFrom()
647 
648   \return The number of bytes received, -1 if an error occured.
649 */
_receiveRequestOnce()650 int vpNetwork::_receiveRequestOnce()
651 {
652   if (receptor_list.size() == 0) {
653     if (verboseMode)
654       vpTRACE("No Receptor!");
655     return -1;
656   }
657 
658   tv.tv_sec = tv_sec;
659 #if TARGET_OS_IPHONE
660   tv.tv_usec = (int)tv_usec;
661 #else
662   tv.tv_usec = tv_usec;
663 #endif
664 
665   FD_ZERO(&readFileDescriptor);
666 
667   for (unsigned int i = 0; i < receptor_list.size(); i++) {
668     if (i == 0)
669       socketMax = receptor_list[i].socketFileDescriptorReceptor;
670 
671     FD_SET((unsigned)receptor_list[i].socketFileDescriptorReceptor, &readFileDescriptor);
672     if (socketMax < receptor_list[i].socketFileDescriptorReceptor)
673       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   } else if (value == 0) {
684     // Timeout
685     return 0;
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 = (int)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           std::cout << "Disconnected : " << inet_ntoa(receptor_list[i].receptorAddress.sin_addr) << std::endl;
698           receptor_list.erase(receptor_list.begin() + (int)i);
699           delete[] buf;
700           return numbytes;
701         } else {
702           std::string returnVal(buf, (unsigned int)numbytes);
703           currentMessageReceived.append(returnVal);
704         }
705         delete[] buf;
706         break;
707       }
708     }
709   }
710 
711   return numbytes;
712 }
713 
714 /*!
715   Receives a message once (in the limit of the Maximum message size value),
716   from a specific emitter. This message can represent an entire request or
717   not. Several calls to this function might be necessary to get the entire
718   request.
719 
720   \warning Requests will be received but not decoded.
721 
722   \sa vpNetwork::receive()
723   \sa vpNetwork::receiveRequestFrom()
724   \sa vpNetwork::receiveRequest()
725   \sa vpNetwork::receiveRequestOnce()
726   \sa vpNetwork::receiveAndDecodeRequest()
727   \sa vpNetwork::receiveAndDecodeRequestFrom()
728   \sa vpNetwork::receiveAndDecodeRequestOnce()
729   \sa vpNetwork::receiveAndDecodeRequestOnceFrom()
730 
731   \param receptorEmitting : Index of the receptor emitting the message.
732 
733   \return The number of bytes received, -1 if an error occured.
734 */
_receiveRequestOnceFrom(const unsigned int & receptorEmitting)735 int vpNetwork::_receiveRequestOnceFrom(const unsigned int &receptorEmitting)
736 {
737   int size = (int)receptor_list.size();
738   int sizeMinusOne = (int)receptor_list.size() - 1;
739   if (size == 0 || receptorEmitting > (unsigned)sizeMinusOne) {
740     if (verboseMode)
741       vpTRACE("No receptor at the specified index!");
742     return -1;
743   }
744 
745   tv.tv_sec = tv_sec;
746 #if TARGET_OS_IPHONE
747   tv.tv_usec = (int)tv_usec;
748 #else
749   tv.tv_usec = tv_usec;
750 #endif
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   } else if (value == 0) {
764     // Timeout
765     return 0;
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 = (int)recv(receptor_list[receptorEmitting].socketFileDescriptorReceptor, buf, max_size_message, 0);
771 #else
772       numbytes = recv((unsigned int)receptor_list[receptorEmitting].socketFileDescriptorReceptor, buf,
773                       (int)max_size_message, 0);
774 #endif
775       if (numbytes <= 0) {
776         std::cout << "Disconnected : " << inet_ntoa(receptor_list[receptorEmitting].receptorAddress.sin_addr)
777                   << std::endl;
778         receptor_list.erase(receptor_list.begin() + (int)receptorEmitting);
779         delete[] buf;
780         return numbytes;
781       } else {
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 #elif !defined(VISP_BUILD_SHARED_LIBS)
793 // Work arround to avoid warning: libvisp_core.a(vpNetwork.cpp.o) has no symbols
dummy_vpNetwork()794 void dummy_vpNetwork(){};
795 #endif
796