Visual Servoing Platform
version 3.7.0
Toggle main menu visibility
Loading...
Searching...
No Matches
vpUDPClient.cpp
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
* UDP Client
32
*/
33
34
#include <cstring>
35
#include <sstream>
36
37
#include <visp3/core/vpConfig.h>
38
39
// inet_ntop() not supported on win XP
40
#ifdef VISP_HAVE_FUNC_INET_NTOP
41
42
#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
// UNIX
43
#include <arpa/inet.h>
44
#include <errno.h>
45
#include <netdb.h>
46
#include <unistd.h>
47
#define DWORD int
48
#else
49
#if defined(__MINGW32__)
50
#ifndef _WIN32_WINNT
51
#define _WIN32_WINNT _WIN32_WINNT_VISTA
// 0x0600
52
#endif
53
#endif
54
55
#if defined(__clang__)
56
// Mute warning : non-portable path to file '<WS2tcpip.h>'; specified path differs in case from file name on disk [-Wnonportable-system-include-path]
57
# pragma clang diagnostic push
58
# pragma clang diagnostic ignored "-Wnonportable-system-include-path"
59
#endif
60
61
#include <Ws2tcpip.h>
62
63
#if defined(__clang__)
64
# pragma clang diagnostic pop
65
#endif
66
67
#endif
68
69
#include <visp3/core/vpUDPClient.h>
70
71
BEGIN_VISP_NAMESPACE
77
vpUDPClient::vpUDPClient
()
78
:
m_is_init
(false), m_serverAddress(), m_serverLength(0), m_socketFileDescriptor()
79
#if defined(_WIN32)
80
,
81
m_wsa()
82
#endif
83
{ }
84
85
vpUDPClient::vpUDPClient
(
const
vpUDPClient
&client)
86
{
87
*
this
= client;
88
}
89
90
vpUDPClient
&
vpUDPClient::operator=
(
const
vpUDPClient
&client)
91
{
92
m_is_init
= client.
m_is_init
;
93
m_serverAddress = client.m_serverAddress;
94
m_serverLength = client.m_serverLength;
95
m_socketFileDescriptor = client.m_socketFileDescriptor;
96
#if defined(_WIN32)
97
m_wsa = client.m_wsa;
98
#endif
99
return
*
this
;
100
}
101
108
vpUDPClient::vpUDPClient
(
const
std::string &hostname,
int
port)
109
:
m_is_init
(false), m_serverAddress(), m_serverLength(0), m_socketFileDescriptor()
110
#if defined(_WIN32)
111
,
112
m_wsa()
113
#endif
114
{
115
init
(hostname, port);
116
}
117
121
vpUDPClient::~vpUDPClient
() { close(); }
122
126
void
vpUDPClient::close()
127
{
128
if
(
m_is_init
) {
129
#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
// UNIX
130
::close(m_socketFileDescriptor);
131
#else
132
closesocket(m_socketFileDescriptor);
133
WSACleanup();
134
#endif
135
m_is_init
=
false
;
136
}
137
}
138
145
void
vpUDPClient::init
(
const
std::string &hostname,
int
port)
146
{
147
// Close connexion if already initialized
148
close();
149
150
#if defined(_WIN32)
151
if
(WSAStartup(MAKEWORD(2, 2), &m_wsa) != 0) {
152
std::stringstream ss;
153
ss <<
"Failed WSAStartup for the server, error code: "
<< WSAGetLastError();
154
throw
vpException
(
vpException::fatalError
, ss.str());
155
}
156
#endif
157
158
/* socket: create the socket */
159
m_socketFileDescriptor = socket(AF_INET, SOCK_DGRAM, 0);
160
#if defined(_WIN32)
161
if
(m_socketFileDescriptor == INVALID_SOCKET)
162
#else
163
if
(m_socketFileDescriptor < 0)
164
#endif
165
throw
vpException
(
vpException::fatalError
,
"Error opening UDP socket for the client!"
);
166
167
/* build the server's Internet address */
168
memset(&m_serverAddress, 0,
sizeof
(m_serverAddress));
169
std::stringstream ss;
170
ss << port;
171
struct
addrinfo hints;
172
struct
addrinfo *result =
nullptr
;
173
struct
addrinfo *ptr =
nullptr
;
174
175
memset(&hints, 0,
sizeof
(hints));
176
hints.ai_family = AF_INET;
177
hints.ai_socktype = SOCK_DGRAM;
178
hints.ai_protocol = IPPROTO_UDP;
179
180
DWORD dwRetval = getaddrinfo(hostname.c_str(), ss.str().c_str(), &hints, &result);
181
if
(dwRetval != 0) {
182
ss.str(
""
);
183
ss <<
"getaddrinfo failed with error: "
<< dwRetval;
184
throw
vpException
(
vpException::fatalError
, ss.str());
185
}
186
187
for
(ptr = result; ptr !=
nullptr
; ptr = ptr->ai_next) {
188
if
(ptr->ai_family == AF_INET && ptr->ai_socktype == SOCK_DGRAM) {
189
m_serverAddress = *(
struct
sockaddr_in *)ptr->ai_addr;
190
break
;
191
}
192
}
193
194
freeaddrinfo(result);
195
196
m_serverLength =
sizeof
(m_serverAddress);
197
m_is_init
=
true
;
198
}
199
222
int
vpUDPClient::receive
(std::string &msg,
int
timeoutMs)
223
{
224
if
(!
m_is_init
) {
225
throw
(
vpException
(
vpException::notInitialized
,
"UDP client is not initialized"
));
226
}
227
fd_set s;
228
FD_ZERO(&s);
229
FD_SET(m_socketFileDescriptor, &s);
230
struct
timeval timeout;
231
if
(timeoutMs > 0) {
232
timeout.tv_sec = timeoutMs / 1000;
233
timeout.tv_usec = (timeoutMs % 1000) * 1000;
234
}
235
int
retval = select(
static_cast<
int
>
(m_socketFileDescriptor) + 1, &s,
nullptr
,
nullptr
, timeoutMs > 0 ? &timeout :
nullptr
);
236
237
if
(retval == -1) {
238
std::cerr <<
"Error select!"
<< std::endl;
239
return
-1;
240
}
241
242
if
(retval > 0) {
243
/* recvfrom: receive a UDP datagram from the server */
244
int
length =
static_cast<
int
>
(recvfrom(m_socketFileDescriptor, m_buf,
sizeof
(m_buf), 0,
245
(
struct
sockaddr *)&m_serverAddress, (socklen_t *)&m_serverLength));
246
if
(length <= 0) {
247
return
length < 0 ? -1 : 0;
248
}
249
250
msg = std::string(m_buf, length);
251
return
length;
252
}
253
254
// Timeout
255
return
0;
256
}
257
268
int
vpUDPClient::receive
(
void
*msg,
size_t
len,
int
timeoutMs)
269
{
270
if
(!
m_is_init
) {
271
throw
(
vpException
(
vpException::notInitialized
,
"UDP client is not initialized"
));
272
}
273
fd_set s;
274
FD_ZERO(&s);
275
FD_SET(m_socketFileDescriptor, &s);
276
struct
timeval timeout;
277
if
(timeoutMs > 0) {
278
timeout.tv_sec = timeoutMs / 1000;
279
timeout.tv_usec = (timeoutMs % 1000) * 1000;
280
}
281
int
retval = select(
static_cast<
int
>
(m_socketFileDescriptor) + 1, &s,
nullptr
,
nullptr
, timeoutMs > 0 ? &timeout :
nullptr
);
282
283
if
(retval == -1) {
284
std::cerr <<
"Error select!"
<< std::endl;
285
return
-1;
286
}
287
288
if
(retval > 0) {
289
/* recvfrom: receive a UDP datagram from the server */
290
int
length =
static_cast<
int
>
(recvfrom(m_socketFileDescriptor, (
char
*)msg,
static_cast<
int
>
(len), 0,
291
(
struct
sockaddr *)&m_serverAddress, (socklen_t *)&m_serverLength));
292
if
(length <= 0) {
293
return
length < 0 ? -1 : 0;
294
}
295
296
return
length;
297
}
298
299
// Timeout
300
return
0;
301
}
302
328
int
vpUDPClient::send
(
const
std::string &msg)
329
{
330
if
(!
m_is_init
) {
331
throw
(
vpException
(
vpException::notInitialized
,
"UDP client is not initialized"
));
332
}
333
if
(msg.size() > VP_MAX_UDP_PAYLOAD) {
334
std::cerr <<
"Message is too long!"
<< std::endl;
335
return
0;
336
}
337
338
/* send the message to the server */
339
#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
// UNIX
340
return
static_cast<
int
>
(
341
sendto(m_socketFileDescriptor, msg.c_str(), msg.size(), 0, (
struct
sockaddr *)&m_serverAddress, m_serverLength));
342
#else
343
return
sendto(m_socketFileDescriptor, msg.c_str(),
static_cast<
int
>
(msg.size()), 0, (
struct
sockaddr *)&m_serverAddress,
344
m_serverLength);
345
#endif
346
}
347
357
int
vpUDPClient::send
(
const
void
*msg,
size_t
len)
358
{
359
if
(!
m_is_init
) {
360
throw
(
vpException
(
vpException::notInitialized
,
"UDP client is not initialized"
));
361
}
362
if
(len > VP_MAX_UDP_PAYLOAD) {
363
std::cerr <<
"Message is too long!"
<< std::endl;
364
return
0;
365
}
366
367
/* send the message to the server */
368
#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
// UNIX
369
return
static_cast<
int
>
(
370
sendto(m_socketFileDescriptor, msg, len, 0, (
struct
sockaddr *)&m_serverAddress, m_serverLength));
371
#else
372
return
sendto(m_socketFileDescriptor, (
char
*)msg,
static_cast<
int
>
(len), 0, (
struct
sockaddr *)&m_serverAddress, m_serverLength);
373
#endif
374
}
375
END_VISP_NAMESPACE
376
#elif !defined(VISP_BUILD_SHARED_LIBS)
377
// Work around to avoid warning: libvisp_core.a(vpUDPClient.cpp.o) has no symbols
378
void
dummy_vpUDPClient() { }
379
#endif
vpException
error that can be emitted by ViSP classes.
Definition
vpException.h:60
vpException::notInitialized
@ notInitialized
Used to indicate that a parameter is not initialized.
Definition
vpException.h:74
vpException::fatalError
@ fatalError
Fatal error.
Definition
vpException.h:72
vpUDPClient::receive
int receive(std::string &msg, int timeoutMs=0)
Definition
vpUDPClient.cpp:222
vpUDPClient::~vpUDPClient
virtual ~vpUDPClient()
Definition
vpUDPClient.cpp:121
vpUDPClient::init
void init(const std::string &hostname, int port)
Definition
vpUDPClient.cpp:145
vpUDPClient::operator=
vpUDPClient & operator=(const vpUDPClient &client)
Definition
vpUDPClient.cpp:90
vpUDPClient::m_is_init
bool m_is_init
Definition
vpUDPClient.h:206
vpUDPClient::vpUDPClient
vpUDPClient()
Definition
vpUDPClient.cpp:77
vpUDPClient::send
int send(const std::string &msg)
Definition
vpUDPClient.cpp:328
BEGIN_VISP_NAMESPACE
Definition
vpMbtDistanceCircle.cpp:55
modules
core
src
tools
network
vpUDPClient.cpp
Generated by
1.17.0