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