39 #include <visp3/core/vpConfig.h>
42 #ifdef VISP_HAVE_FUNC_INET_NTOP
44 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
45 #include <arpa/inet.h>
50 #define WSAGetLastError() strerror(errno)
52 #if defined(__MINGW32__)
56 #define _WIN32_WINNT _WIN32_WINNT_VISTA
66 #include <visp3/core/vpUDPServer.h>
76 : m_clientAddress(), m_clientLength(0), m_serverAddress(), m_socketFileDescriptor(0)
92 : m_clientAddress(), m_clientLength(0), m_serverAddress(), m_socketFileDescriptor(0)
103 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
104 close(m_socketFileDescriptor);
106 closesocket(m_socketFileDescriptor);
111 void vpUDPServer::init(
const std::string &hostname,
int port)
114 if (WSAStartup(MAKEWORD(2, 2), &m_wsa) != 0) {
115 std::stringstream ss;
116 ss <<
"Failed WSAStartup for the server, error code: " << WSAGetLastError();
122 m_socketFileDescriptor = socket(AF_INET, SOCK_DGRAM, 0);
124 if (m_socketFileDescriptor == INVALID_SOCKET)
126 if (m_socketFileDescriptor < 0)
135 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
137 setsockopt(m_socketFileDescriptor, SOL_SOCKET, SO_REUSEADDR, (
const void *)&optval,
sizeof(
int));
139 const char optval = 1;
140 setsockopt(m_socketFileDescriptor, SOL_SOCKET, SO_REUSEADDR, (
const char *)&optval,
sizeof(
int));
144 memset(&m_serverAddress, 0,
sizeof(m_serverAddress));
145 if (hostname.empty()) {
146 m_serverAddress.sin_family = AF_INET;
147 m_serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
148 m_serverAddress.sin_port = htons((
unsigned short)port);
151 std::stringstream ss;
153 struct addrinfo hints;
154 struct addrinfo *result =
nullptr;
155 struct addrinfo *ptr =
nullptr;
157 memset(&hints, 0,
sizeof(hints));
158 hints.ai_family = AF_INET;
159 hints.ai_socktype = SOCK_DGRAM;
160 hints.ai_protocol = IPPROTO_UDP;
162 DWORD dwRetval = getaddrinfo(hostname.c_str(), ss.str().c_str(), &hints, &result);
165 ss <<
"getaddrinfo failed with error: " << dwRetval;
169 for (ptr = result; ptr !=
nullptr; ptr = ptr->ai_next) {
170 if (ptr->ai_family == AF_INET && ptr->ai_socktype == SOCK_DGRAM) {
171 m_serverAddress = *(
struct sockaddr_in *)ptr->ai_addr;
176 freeaddrinfo(result);
180 if (bind(m_socketFileDescriptor, (
struct sockaddr *)&m_serverAddress,
sizeof(m_serverAddress)) < 0)
183 m_clientLength =
sizeof(m_clientAddress);
199 std::string hostInfo =
"";
200 return receive(msg, hostInfo, timeoutMs);
219 FD_SET(m_socketFileDescriptor, &s);
220 struct timeval timeout;
222 timeout.tv_sec = timeoutMs / 1000;
223 timeout.tv_usec = (timeoutMs % 1000) * 1000;
225 int retval = select((
int)m_socketFileDescriptor + 1, &s,
nullptr,
nullptr, timeoutMs > 0 ? &timeout :
nullptr);
228 std::cerr <<
"Error select!" << std::endl;
234 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
235 int length =
static_cast<int>(recvfrom(m_socketFileDescriptor, m_buf,
sizeof(m_buf), 0,
236 (
struct sockaddr *)&m_clientAddress, (socklen_t *)&m_clientLength));
239 recvfrom(m_socketFileDescriptor, m_buf,
sizeof(m_buf), 0, (
struct sockaddr *)&m_clientAddress, &m_clientLength);
242 return length < 0 ? -1 : 0;
245 msg = std::string(m_buf, length);
248 char hostname[NI_MAXHOST];
249 char servInfo[NI_MAXSERV];
250 DWORD dwRetval = getnameinfo((
struct sockaddr *)&m_clientAddress,
sizeof(
struct sockaddr), hostname, NI_MAXHOST,
251 servInfo, NI_MAXSERV, NI_NUMERICSERV);
253 std::string hostName =
"", hostIp =
"", hostPort =
"";
255 std::cerr <<
"getnameinfo failed with error: " << WSAGetLastError() << std::endl;
262 char result[INET_ADDRSTRLEN];
263 const char *ptr = inet_ntop(AF_INET, (
void *)&m_clientAddress.sin_addr, result,
sizeof(result));
264 if (ptr ==
nullptr) {
265 std::cerr <<
"inet_ntop failed with error: " << WSAGetLastError() << std::endl;
271 std::stringstream ss;
272 ss << hostName <<
" " << hostIp <<
" " << hostPort;
294 if (msg.size() > VP_MAX_UDP_PAYLOAD) {
295 std::cerr <<
"Message is too long!" << std::endl;
300 memset(&m_clientAddress, 0,
sizeof(m_clientAddress));
301 std::stringstream ss;
303 struct addrinfo hints;
304 struct addrinfo *result =
nullptr;
305 struct addrinfo *ptr =
nullptr;
307 memset(&hints, 0,
sizeof(hints));
308 hints.ai_family = AF_INET;
309 hints.ai_socktype = SOCK_DGRAM;
310 hints.ai_protocol = IPPROTO_UDP;
312 DWORD dwRetval = getaddrinfo(hostname.c_str(), ss.str().c_str(), &hints, &result);
315 ss <<
"getaddrinfo failed with error: " << dwRetval;
319 for (ptr = result; ptr !=
nullptr; ptr = ptr->ai_next) {
320 if (ptr->ai_family == AF_INET && ptr->ai_socktype == SOCK_DGRAM) {
321 m_clientAddress = *(
struct sockaddr_in *)ptr->ai_addr;
326 freeaddrinfo(result);
329 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
330 return static_cast<int>(
331 sendto(m_socketFileDescriptor, msg.c_str(), msg.size(), 0, (
struct sockaddr *)&m_clientAddress, m_clientLength));
333 return sendto(m_socketFileDescriptor, msg.c_str(), (
int)msg.size(), 0, (
struct sockaddr *)&m_clientAddress,
338 #elif !defined(VISP_BUILD_SHARED_LIBS)
340 void dummy_vpUDPServer() { };
error that can be emitted by ViSP classes.
int send(const std::string &msg, const std::string &hostname, int port)
int receive(std::string &msg, int timeoutMs=0)