Visual Servoing Platform version 3.6.0
Loading...
Searching...
No Matches
vpNetwork.h
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2023 by Inria. All rights reserved.
4 *
5 * This software is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 * See the file LICENSE.txt at the root directory of this source
10 * distribution for additional information about the GNU GPL.
11 *
12 * For using ViSP with software that can not be combined with the GNU
13 * GPL, please contact Inria about acquiring a ViSP Professional
14 * Edition License.
15 *
16 * See https://visp.inria.fr for more information.
17 *
18 * This software was developed at:
19 * Inria Rennes - Bretagne Atlantique
20 * Campus Universitaire de Beaulieu
21 * 35042 Rennes Cedex
22 * France
23 *
24 * If you have questions regarding the use of this file, please contact
25 * Inria at visp@inria.fr
26 *
27 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29 *
30 * Description:
31 * TCP Network
32 */
33
34#ifndef vpNetwork_H
35#define vpNetwork_H
36
37#include <visp3/core/vpConfig.h>
38#include <visp3/core/vpRequest.h>
39
40#include <iostream>
41#include <stdio.h>
42#include <string.h>
43#include <vector>
44#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
45#include <sys/select.h>
46#endif
47
48 // inet_ntop() not supported on win XP
49#ifdef VISP_HAVE_FUNC_INET_NTOP
50
51#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
52#include <arpa/inet.h>
53#include <netdb.h>
54#include <netinet/in.h>
55#include <sys/socket.h>
56#include <unistd.h>
57#else
58#include <io.h>
59//# include<winsock.h>
60#include <winsock2.h>
61//# pragma comment(lib, "ws2_32.lib") // Done by CMake in main CMakeLists.txt
62#endif
63
64#if defined(__APPLE__) && defined(__MACH__) // Apple OSX and iOS (Darwin)
65#include <TargetConditionals.h> // To detect OSX or IOS using TARGET_OS_IPHONE or TARGET_OS_IOS macro
66#endif
67
85class VISP_EXPORT vpNetwork
86{
87protected:
88#ifndef DOXYGEN_SHOULD_SKIP_THIS
89 struct vpReceptor
90 {
91#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
92 int socketFileDescriptorReceptor;
93 socklen_t receptorAddressSize;
94#else
95 SOCKET socketFileDescriptorReceptor;
96 int receptorAddressSize;
97#endif
98 struct sockaddr_in receptorAddress;
99 std::string receptorIP;
100
101 vpReceptor() : socketFileDescriptorReceptor(0), receptorAddressSize(), receptorAddress(), receptorIP() { }
102 };
103
104 struct vpEmitter
105 {
106 struct sockaddr_in emitterAddress;
107#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
108 int socketFileDescriptorEmitter;
109#else
110 SOCKET socketFileDescriptorEmitter;
111#endif
112 vpEmitter() : emitterAddress(), socketFileDescriptorEmitter(0)
113 {
114 emitterAddress.sin_family = AF_INET;
115 emitterAddress.sin_addr.s_addr = INADDR_ANY;
116 emitterAddress.sin_port = 0;
117 socketFileDescriptorEmitter = 0;
118 }
119 };
120#endif
121
122 //######## PARAMETERS ########
123 //# #
124 //############################
125
126 vpEmitter emitter;
127 std::vector<vpReceptor> receptor_list;
129#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
131#else
132 SOCKET socketMax;
133#endif
134
135 // Message Handling
136 std::vector<vpRequest *> request_list;
137
138 unsigned int max_size_message;
139 std::string separator;
140 std::string beginning;
141 std::string end;
142 std::string param_sep;
143
145
146 struct timeval tv;
147 long tv_sec;
149
151
152private:
153 std::vector<int> privHandleRequests();
154 int privHandleFirstRequest();
155
156 void privReceiveRequest();
157 void privReceiveRequestFrom(const unsigned int &receptorEmitting);
158 int privReceiveRequestOnce();
159 int privReceiveRequestOnceFrom(const unsigned int &receptorEmitting);
160
161public:
162 vpNetwork();
163 virtual ~vpNetwork();
164
165 void addDecodingRequest(vpRequest *);
166
167 int getReceptorIndex(const char *name);
168
176 std::string getRequestIdFromIndex(const int &ind)
177 {
178 if (ind >= (int)request_list.size() || ind < 0)
179 return "";
180 return request_list[(unsigned)ind]->getId();
181 }
182
190 unsigned int getMaxSizeReceivedMessage() { return max_size_message; }
191
192 void print(const char *id = "");
193
194 template <typename T> int receive(T *object, const unsigned int &sizeOfObject = sizeof(T));
195 template <typename T>
196 int receiveFrom(T *object, const unsigned int &receptorEmitting, const unsigned int &sizeOfObject = sizeof(T));
197
198 std::vector<int> receiveRequest();
199 std::vector<int> receiveRequestFrom(const unsigned int &receptorEmitting);
200 int receiveRequestOnce();
201 int receiveRequestOnceFrom(const unsigned int &receptorEmitting);
202
203 std::vector<int> receiveAndDecodeRequest();
204 std::vector<int> receiveAndDecodeRequestFrom(const unsigned int &receptorEmitting);
205 int receiveAndDecodeRequestOnce();
206 int receiveAndDecodeRequestOnceFrom(const unsigned int &receptorEmitting);
207
208 void removeDecodingRequest(const char *);
209
210 template <typename T> int send(T *object, const int unsigned &sizeOfObject = sizeof(T));
211 template <typename T> int sendTo(T *object, const unsigned int &dest, const unsigned int &sizeOfObject = sizeof(T));
212
213 int sendRequest(vpRequest &req);
214 int sendRequestTo(vpRequest &req, const unsigned int &dest);
215
216 int sendAndEncodeRequest(vpRequest &req);
217 int sendAndEncodeRequestTo(vpRequest &req, const unsigned int &dest);
218
226 void setMaxSizeReceivedMessage(const unsigned int &s) { max_size_message = s; }
227
236 void setTimeoutSec(const long &sec) { tv_sec = sec; }
237
246 void setTimeoutUSec(const long &usec) { tv_usec = usec; }
247
253 void setVerbose(const bool &mode) { verboseMode = mode; }
254};
255
256//######## Definition of Template Functions ########
257//# #
258//##################################################
259
280template <typename T> int vpNetwork::receive(T *object, const unsigned int &sizeOfObject)
281{
282 if (receptor_list.size() == 0) {
283 if (verboseMode)
284 vpTRACE("No receptor");
285 return -1;
286 }
287
288 tv.tv_sec = tv_sec;
289#ifdef TARGET_OS_IPHONE
290 tv.tv_usec = (int)tv_usec;
291#else
292 tv.tv_usec = tv_usec;
293#endif
294
295 FD_ZERO(&readFileDescriptor);
296
297 for (unsigned int i = 0; i < receptor_list.size(); i++) {
298 FD_SET((unsigned int)receptor_list[i].socketFileDescriptorReceptor, &readFileDescriptor);
299
300 if (i == 0)
301 socketMax = receptor_list[i].socketFileDescriptorReceptor;
302
303 if (socketMax < receptor_list[i].socketFileDescriptorReceptor)
304 socketMax = receptor_list[i].socketFileDescriptorReceptor;
305 }
306
307 int value = select((int)socketMax + 1, &readFileDescriptor, NULL, NULL, &tv);
308 int numbytes = 0;
309
310 if (value == -1) {
311 if (verboseMode)
312 vpERROR_TRACE("Select error");
313 return -1;
314 }
315 else if (value == 0) {
316 // Timeout
317 return 0;
318 }
319 else {
320 for (unsigned int i = 0; i < receptor_list.size(); i++) {
321 if (FD_ISSET((unsigned int)receptor_list[i].socketFileDescriptorReceptor, &readFileDescriptor)) {
322#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
323 numbytes = recv(receptor_list[i].socketFileDescriptorReceptor, (char *)(void *)object, sizeOfObject, 0);
324#else
325 numbytes = recv((unsigned int)receptor_list[i].socketFileDescriptorReceptor, (char *)(void *)object,
326 (int)sizeOfObject, 0);
327#endif
328 if (numbytes <= 0) {
329 std::cout << "Disconnected : " << inet_ntoa(receptor_list[i].receptorAddress.sin_addr) << std::endl;
330 receptor_list.erase(receptor_list.begin() + (int)i);
331 return numbytes;
332 }
333
334 break;
335 }
336 }
337 }
338
339 return numbytes;
340}
341
363template <typename T>
364int vpNetwork::receiveFrom(T *object, const unsigned int &receptorEmitting, const unsigned int &sizeOfObject)
365{
366 if (receptor_list.size() == 0 || receptorEmitting > (unsigned int)receptor_list.size() - 1) {
367 if (verboseMode)
368 vpTRACE("No receptor at the specified index");
369 return -1;
370 }
371
372 tv.tv_sec = tv_sec;
373#ifdef TARGET_OS_IPHONE
374 tv.tv_usec = (int)tv_usec;
375#else
376 tv.tv_usec = tv_usec;
377#endif
378
379 FD_ZERO(&readFileDescriptor);
380
381 socketMax = receptor_list[receptorEmitting].socketFileDescriptorReceptor;
382 FD_SET((unsigned int)receptor_list[receptorEmitting].socketFileDescriptorReceptor, &readFileDescriptor);
383
384 int value = select((int)socketMax + 1, &readFileDescriptor, NULL, NULL, &tv);
385 int numbytes = 0;
386
387 if (value == -1) {
388 if (verboseMode)
389 vpERROR_TRACE("Select error");
390 return -1;
391 }
392 else if (value == 0) {
393 // timeout
394 return 0;
395 }
396 else {
397 if (FD_ISSET((unsigned int)receptor_list[receptorEmitting].socketFileDescriptorReceptor, &readFileDescriptor)) {
398#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
399 numbytes =
400 recv(receptor_list[receptorEmitting].socketFileDescriptorReceptor, (char *)(void *)object, sizeOfObject, 0);
401#else
402 numbytes = recv((unsigned int)receptor_list[receptorEmitting].socketFileDescriptorReceptor,
403 (char *)(void *)object, (int)sizeOfObject, 0);
404#endif
405 if (numbytes <= 0) {
406 std::cout << "Disconnected : " << inet_ntoa(receptor_list[receptorEmitting].receptorAddress.sin_addr)
407 << std::endl;
408 receptor_list.erase(receptor_list.begin() + (int)receptorEmitting);
409 return numbytes;
410 }
411 }
412 }
413
414 return numbytes;
415}
416
438template <typename T> int vpNetwork::send(T *object, const unsigned int &sizeOfObject)
439{
440 if (receptor_list.size() == 0) {
441 if (verboseMode)
442 vpTRACE("No receptor !");
443 return 0;
444 }
445
446 int flags = 0;
447 //#if ! defined(APPLE) && ! defined(SOLARIS) && ! defined(_WIN32)
448#if defined(__linux__)
449 flags = MSG_NOSIGNAL; // Only for Linux
450#endif
451
452#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
453 return sendto(receptor_list[0].socketFileDescriptorReceptor, (const char *)(void *)object, sizeOfObject, flags,
454 (sockaddr *)&receptor_list[0].receptorAddress, receptor_list[0].receptorAddressSize);
455#else
456 return sendto(receptor_list[0].socketFileDescriptorReceptor, (const char *)(void *)object, (int)sizeOfObject, flags,
457 (sockaddr *)&receptor_list[0].receptorAddress, receptor_list[0].receptorAddressSize);
458#endif
459}
460
482template <typename T> int vpNetwork::sendTo(T *object, const unsigned int &dest, const unsigned int &sizeOfObject)
483{
484 if (receptor_list.size() == 0 || dest > (unsigned int)receptor_list.size() - 1) {
485 if (verboseMode)
486 vpTRACE("No receptor at the specified index.");
487 return 0;
488 }
489
490 int flags = 0;
491 //#if ! defined(APPLE) && ! defined(SOLARIS) && ! defined(_WIN32)
492#if defined(__linux__)
493 flags = MSG_NOSIGNAL; // Only for Linux
494#endif
495
496#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
497 return sendto(receptor_list[dest].socketFileDescriptorReceptor, (const char *)(void *)object, sizeOfObject, flags,
498 (sockaddr *)&receptor_list[dest].receptorAddress, receptor_list[dest].receptorAddressSize);
499#else
500 return sendto(receptor_list[dest].socketFileDescriptorReceptor, (const char *)(void *)object, (int)sizeOfObject,
501 flags, (sockaddr *)&receptor_list[dest].receptorAddress, receptor_list[dest].receptorAddressSize);
502#endif
503}
504
505#endif
506#endif
This class represents a Transmission Control Protocol (TCP) network.
Definition vpNetwork.h:86
int sendTo(T *object, const unsigned int &dest, const unsigned int &sizeOfObject=sizeof(T))
Definition vpNetwork.h:482
long tv_sec
Definition vpNetwork.h:147
std::string getRequestIdFromIndex(const int &ind)
Definition vpNetwork.h:176
int socketMax
Definition vpNetwork.h:130
fd_set readFileDescriptor
Definition vpNetwork.h:128
void setTimeoutUSec(const long &usec)
Definition vpNetwork.h:246
int receiveFrom(T *object, const unsigned int &receptorEmitting, const unsigned int &sizeOfObject=sizeof(T))
Definition vpNetwork.h:364
void setVerbose(const bool &mode)
Definition vpNetwork.h:253
bool verboseMode
Definition vpNetwork.h:150
std::string currentMessageReceived
Definition vpNetwork.h:144
std::vector< vpRequest * > request_list
Definition vpNetwork.h:136
int send(T *object, const int unsigned &sizeOfObject=sizeof(T))
long tv_usec
Definition vpNetwork.h:148
std::string beginning
Definition vpNetwork.h:140
std::vector< vpReceptor > receptor_list
Definition vpNetwork.h:127
struct timeval tv
Definition vpNetwork.h:146
vpEmitter emitter
Definition vpNetwork.h:126
void setTimeoutSec(const long &sec)
Definition vpNetwork.h:236
int receive(T *object, const unsigned int &sizeOfObject=sizeof(T))
Definition vpNetwork.h:280
std::string separator
Definition vpNetwork.h:139
std::string param_sep
Definition vpNetwork.h:142
unsigned int getMaxSizeReceivedMessage()
Definition vpNetwork.h:190
unsigned int max_size_message
Definition vpNetwork.h:138
void setMaxSizeReceivedMessage(const unsigned int &s)
Definition vpNetwork.h:226
std::string end
Definition vpNetwork.h:141
This the request that will transit on the network.
Definition vpRequest.h:127
#define vpTRACE
Definition vpDebug.h:411
#define vpERROR_TRACE
Definition vpDebug.h:388