Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpNetwork.h
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2025 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 VP_NETWORK_H
35#define VP_NETWORK_H
36
37// Specific case for UWP to introduce a workaround
38// error C4996: 'gethostbyname': Use getaddrinfo() or GetAddrInfoW() instead or define _WINSOCK_DEPRECATED_NO_WARNINGS to disable deprecated API warnings
39#if defined(WINRT) || defined(_WIN32)
40#ifndef _WINSOCK_DEPRECATED_NO_WARNINGS
41#define _WINSOCK_DEPRECATED_NO_WARNINGS
42#endif
43#endif
44
45#include <visp3/core/vpConfig.h>
46#include <visp3/core/vpDebug.h>
47#include <visp3/core/vpRequest.h>
48
49#include <iostream>
50#include <stdio.h>
51#include <string.h>
52#include <vector>
53#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
54#include <sys/select.h>
55#endif
56
57 // inet_ntop() not supported on win XP
58#ifdef VISP_HAVE_FUNC_INET_NTOP
59
60#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
61#include <arpa/inet.h>
62#include <netdb.h>
63#include <netinet/in.h>
64#include <sys/socket.h>
65#include <unistd.h>
66#else
67#include <io.h>
68
69#if defined(__clang__)
70// Mute warning : non-portable path to file '<WinSock2.h>'; specified path differs in case from file name on disk [-Wnonportable-system-include-path]
71# pragma clang diagnostic push
72# pragma clang diagnostic ignored "-Wnonportable-system-include-path"
73#endif
74
75#include <winsock2.h>
76
77#if defined(__clang__)
78# pragma clang diagnostic pop
79#endif
80
81#endif
82
83#if defined(__APPLE__) && defined(__MACH__) // Apple OSX and iOS (Darwin)
84#include <TargetConditionals.h> // To detect OSX or IOS using TARGET_OS_IPHONE or TARGET_OS_IOS macro
85#endif
86
105class VISP_EXPORT vpNetwork
106{
107protected:
108#ifndef DOXYGEN_SHOULD_SKIP_THIS
109 struct vpReceptor
110 {
111#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
112 int socketFileDescriptorReceptor;
113 socklen_t receptorAddressSize;
114#else
115 SOCKET socketFileDescriptorReceptor;
116 int receptorAddressSize;
117#endif
118 struct sockaddr_in receptorAddress;
119 std::string receptorIP;
120
121 vpReceptor() : socketFileDescriptorReceptor(0), receptorAddressSize(), receptorAddress(), receptorIP() { }
122 };
123
124 struct vpEmitter
125 {
126 struct sockaddr_in emitterAddress;
127#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
128 int socketFileDescriptorEmitter;
129#else
130 SOCKET socketFileDescriptorEmitter;
131#endif
132 vpEmitter() : emitterAddress(), socketFileDescriptorEmitter(0)
133 {
134 emitterAddress.sin_family = AF_INET;
135 emitterAddress.sin_addr.s_addr = INADDR_ANY;
136 emitterAddress.sin_port = 0;
137 socketFileDescriptorEmitter = 0;
138 }
139 };
140#endif
141
142 //######## PARAMETERS ########
143 //# #
144 //############################
145
146 vpEmitter emitter;
147 std::vector<vpReceptor> receptor_list;
149#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
151#else
152 SOCKET socketMax;
153#endif
154
155 // Message Handling
156 std::vector<vpRequest *> request_list;
157
158 unsigned int max_size_message;
159 std::string separator;
160 std::string beginning;
161 std::string end;
162 std::string param_sep;
163
165
166 struct timeval tv;
167 long tv_sec;
169
171
172private:
173 std::vector<int> privHandleRequests();
174 int privHandleFirstRequest();
175
176 void privReceiveRequest();
177 void privReceiveRequestFrom(const unsigned int &receptorEmitting);
178 int privReceiveRequestOnce();
179 int privReceiveRequestOnceFrom(const unsigned int &receptorEmitting);
180
181public:
182 vpNetwork();
183 vpNetwork(const vpNetwork &network);
184 virtual ~vpNetwork();
185
186 vpNetwork &operator=(const vpNetwork &network);
187
189
190 int getReceptorIndex(const char *name);
191
199 std::string getRequestIdFromIndex(const int &ind)
200 {
201 if (ind >= static_cast<int>(request_list.size()) || ind < 0) {
202 return "";
203 }
204 return request_list[static_cast<unsigned int>(ind)]->getId();
205 }
206
215
216 void print(const char *id = "");
217
218 template <typename T> int receive(T *object, const unsigned int &sizeOfObject = sizeof(T));
219 template <typename T>
220 int receiveFrom(T *object, const unsigned int &receptorEmitting, const unsigned int &sizeOfObject = sizeof(T));
221
222 std::vector<int> receiveRequest();
223 std::vector<int> receiveRequestFrom(const unsigned int &receptorEmitting);
224 int receiveRequestOnce();
225 int receiveRequestOnceFrom(const unsigned int &receptorEmitting);
226
227 std::vector<int> receiveAndDecodeRequest();
228 std::vector<int> receiveAndDecodeRequestFrom(const unsigned int &receptorEmitting);
229 int receiveAndDecodeRequestOnce();
230 int receiveAndDecodeRequestOnceFrom(const unsigned int &receptorEmitting);
231
232 void removeDecodingRequest(const char *);
233
234 template <typename T> int send(T *object, const int unsigned &sizeOfObject = sizeof(T));
235 template <typename T> int sendTo(T *object, const unsigned int &dest, const unsigned int &sizeOfObject = sizeof(T));
236
237 int sendRequest(vpRequest &req);
238 int sendRequestTo(vpRequest &req, const unsigned int &dest);
239
241 int sendAndEncodeRequestTo(vpRequest &req, const unsigned int &dest);
242
250 void setMaxSizeReceivedMessage(const unsigned int &s) { max_size_message = s; }
251
260 void setTimeoutSec(const long &sec) { tv_sec = sec; }
261
270 void setTimeoutUSec(const long &usec) { tv_usec = usec; }
271
277 void setVerbose(const bool &mode) { verboseMode = mode; }
278};
279
280//######## Definition of Template Functions ########
281//# #
282//##################################################
283
304template <typename T> int vpNetwork::receive(T *object, const unsigned int &sizeOfObject)
305{
306 if (receptor_list.size() == 0) {
307 if (verboseMode)
308 vpTRACE("No receptor");
309 return -1;
310 }
311
312 tv.tv_sec = tv_sec;
313#ifdef TARGET_OS_IPHONE
314 tv.tv_usec = static_cast<int>(tv_usec);
315#else
316 tv.tv_usec = tv_usec;
317#endif
318
319 FD_ZERO(&readFileDescriptor);
320
321 for (unsigned int i = 0; i < receptor_list.size(); i++) {
322 FD_SET(static_cast<unsigned int>(receptor_list[i].socketFileDescriptorReceptor), &readFileDescriptor);
323
324 if (i == 0)
325 socketMax = receptor_list[i].socketFileDescriptorReceptor;
326
327 if (socketMax < receptor_list[i].socketFileDescriptorReceptor)
328 socketMax = receptor_list[i].socketFileDescriptorReceptor;
329 }
330
331 int value = select(static_cast<int>(socketMax) + 1, &readFileDescriptor, nullptr, nullptr, &tv);
332 int numbytes = 0;
333
334 if (value == -1) {
335 if (verboseMode)
336 vpERROR_TRACE("Select error");
337 return -1;
338 }
339 else if (value == 0) {
340 // Timeout
341 return 0;
342 }
343 else {
344 for (unsigned int i = 0; i < receptor_list.size(); i++) {
345 if (FD_ISSET(static_cast<unsigned int>(receptor_list[i].socketFileDescriptorReceptor), &readFileDescriptor)) {
346#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
347 numbytes = recv(receptor_list[i].socketFileDescriptorReceptor, (char *)(void *)object, sizeOfObject, 0);
348#else
349 numbytes = recv(static_cast<unsigned int>(receptor_list[i].socketFileDescriptorReceptor), (char *)(void *)object,
350 static_cast<int>(sizeOfObject), 0);
351#endif
352 if (numbytes <= 0) {
353 std::cout << "Disconnected : " << inet_ntoa(receptor_list[i].receptorAddress.sin_addr) << std::endl;
354 receptor_list.erase(receptor_list.begin() + static_cast<int>(i));
355 return numbytes;
356 }
357
358 break;
359 }
360 }
361 }
362
363 return numbytes;
364}
365
387template <typename T>
388int vpNetwork::receiveFrom(T *object, const unsigned int &receptorEmitting, const unsigned int &sizeOfObject)
389{
390 if (receptor_list.size() == 0 || receptorEmitting > static_cast<unsigned int>(receptor_list.size()) - 1) {
391 if (verboseMode)
392 vpTRACE("No receptor at the specified index");
393 return -1;
394 }
395
396 tv.tv_sec = tv_sec;
397#ifdef TARGET_OS_IPHONE
398 tv.tv_usec = static_cast<int>(tv_usec);
399#else
400 tv.tv_usec = tv_usec;
401#endif
402
403 FD_ZERO(&readFileDescriptor);
404
405 socketMax = receptor_list[receptorEmitting].socketFileDescriptorReceptor;
406 FD_SET(static_cast<unsigned int>(receptor_list[receptorEmitting].socketFileDescriptorReceptor), &readFileDescriptor);
407
408 int value = select(static_cast<int>(socketMax) + 1, &readFileDescriptor, nullptr, nullptr, &tv);
409 int numbytes = 0;
410
411 if (value == -1) {
412 if (verboseMode)
413 vpERROR_TRACE("Select error");
414 return -1;
415 }
416 else if (value == 0) {
417 // timeout
418 return 0;
419 }
420 else {
421 if (FD_ISSET(static_cast<unsigned int>(receptor_list[receptorEmitting].socketFileDescriptorReceptor), &readFileDescriptor)) {
422#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
423 numbytes =
424 recv(receptor_list[receptorEmitting].socketFileDescriptorReceptor, (char *)(void *)object, sizeOfObject, 0);
425#else
426 numbytes = recv(static_cast<unsigned int>(receptor_list[receptorEmitting].socketFileDescriptorReceptor),
427 (char *)(void *)object, static_cast<int>(sizeOfObject), 0);
428#endif
429 if (numbytes <= 0) {
430 std::cout << "Disconnected : " << inet_ntoa(receptor_list[receptorEmitting].receptorAddress.sin_addr)
431 << std::endl;
432 receptor_list.erase(receptor_list.begin() + static_cast<int>(receptorEmitting));
433 return numbytes;
434 }
435 }
436 }
437
438 return numbytes;
439}
440
462template <typename T> int vpNetwork::send(T *object, const unsigned int &sizeOfObject)
463{
464 if (receptor_list.size() == 0) {
465 if (verboseMode)
466 vpTRACE("No receptor !");
467 return 0;
468 }
469
470 int flags = 0;
471 //#if ! defined(APPLE) && ! defined(SOLARIS) && ! defined(_WIN32)
472#if defined(__linux__)
473 flags = MSG_NOSIGNAL; // Only for Linux
474#endif
475
476#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
477 return sendto(receptor_list[0].socketFileDescriptorReceptor, (const char *)(void *)object, sizeOfObject, flags,
478 (sockaddr *)&receptor_list[0].receptorAddress, receptor_list[0].receptorAddressSize);
479#else
480 return sendto(receptor_list[0].socketFileDescriptorReceptor, (const char *)(void *)object, static_cast<int>(sizeOfObject), flags,
481 (sockaddr *)&receptor_list[0].receptorAddress, receptor_list[0].receptorAddressSize);
482#endif
483}
484
506template <typename T> int vpNetwork::sendTo(T *object, const unsigned int &dest, const unsigned int &sizeOfObject)
507{
508 if (receptor_list.size() == 0 || dest > static_cast<unsigned int>(receptor_list.size()) - 1) {
509 if (verboseMode)
510 vpTRACE("No receptor at the specified index.");
511 return 0;
512 }
513
514 int flags = 0;
515 //#if ! defined(APPLE) && ! defined(SOLARIS) && ! defined(_WIN32)
516#if defined(__linux__)
517 flags = MSG_NOSIGNAL; // Only for Linux
518#endif
519
520#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
521 return sendto(receptor_list[dest].socketFileDescriptorReceptor, (const char *)(void *)object, sizeOfObject, flags,
522 (sockaddr *)&receptor_list[dest].receptorAddress, receptor_list[dest].receptorAddressSize);
523#else
524 return sendto(receptor_list[dest].socketFileDescriptorReceptor, (const char *)(void *)object, static_cast<int>(sizeOfObject),
525 flags, (sockaddr *)&receptor_list[dest].receptorAddress, receptor_list[dest].receptorAddressSize);
526#endif
527}
528END_VISP_NAMESPACE
529#endif
530#endif
int sendTo(T *object, const unsigned int &dest, const unsigned int &sizeOfObject=sizeof(T))
Definition vpNetwork.h:506
long tv_sec
Definition vpNetwork.h:167
vpNetwork & operator=(const vpNetwork &network)
Definition vpNetwork.cpp:76
std::string getRequestIdFromIndex(const int &ind)
Definition vpNetwork.h:199
int sendRequest(vpRequest &req)
int socketMax
Definition vpNetwork.h:150
fd_set readFileDescriptor
Definition vpNetwork.h:148
void setTimeoutUSec(const long &usec)
Definition vpNetwork.h:270
int receiveFrom(T *object, const unsigned int &receptorEmitting, const unsigned int &sizeOfObject=sizeof(T))
Definition vpNetwork.h:388
void setVerbose(const bool &mode)
Definition vpNetwork.h:277
bool verboseMode
Definition vpNetwork.h:170
std::string currentMessageReceived
Definition vpNetwork.h:164
int sendAndEncodeRequestTo(vpRequest &req, const unsigned int &dest)
std::vector< vpRequest * > request_list
Definition vpNetwork.h:156
int send(T *object, const int unsigned &sizeOfObject=sizeof(T))
int sendAndEncodeRequest(vpRequest &req)
long tv_usec
Definition vpNetwork.h:168
std::string beginning
Definition vpNetwork.h:160
int sendRequestTo(vpRequest &req, const unsigned int &dest)
std::vector< vpReceptor > receptor_list
Definition vpNetwork.h:147
void addDecodingRequest(vpRequest *)
struct timeval tv
Definition vpNetwork.h:166
vpEmitter emitter
Definition vpNetwork.h:146
void setTimeoutSec(const long &sec)
Definition vpNetwork.h:260
int receive(T *object, const unsigned int &sizeOfObject=sizeof(T))
Definition vpNetwork.h:304
std::string separator
Definition vpNetwork.h:159
std::string param_sep
Definition vpNetwork.h:162
unsigned int getMaxSizeReceivedMessage()
Definition vpNetwork.h:214
int getReceptorIndex(const char *name)
unsigned int max_size_message
Definition vpNetwork.h:158
void setMaxSizeReceivedMessage(const unsigned int &s)
Definition vpNetwork.h:250
std::string end
Definition vpNetwork.h:161
This the request that will transit on the network.
Definition vpRequest.h:128
#define vpTRACE
Definition vpDebug.h:450
#define vpERROR_TRACE
Definition vpDebug.h:423