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__))) // UNIX 45 # include <arpa/inet.h> 50 # define WSAGetLastError() strerror(errno) 52 # if defined(__MINGW32__) 53 # define _WIN32_WINNT _WIN32_WINNT_VISTA // 0x0600 55 # include <Ws2tcpip.h> 58 #include <visp3/core/vpUDPServer.h> 67 : m_clientAddress(), m_clientLength(0), m_serverAddress(), m_socketFileDescriptor(0)
83 : m_clientAddress(), m_clientLength(0), m_serverAddress(), m_socketFileDescriptor(0)
94 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX 95 close(m_socketFileDescriptor);
97 closesocket(m_socketFileDescriptor);
102 void vpUDPServer::init(
const std::string &hostname,
const int port)
105 if (WSAStartup(MAKEWORD(2, 2), &m_wsa) != 0) {
106 std::stringstream ss;
107 ss <<
"Failed WSAStartup for the server, error code: " << WSAGetLastError();
113 m_socketFileDescriptor = socket(AF_INET, SOCK_DGRAM, 0);
115 if (m_socketFileDescriptor == INVALID_SOCKET)
117 if (m_socketFileDescriptor < 0)
126 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX 128 setsockopt(m_socketFileDescriptor, SOL_SOCKET, SO_REUSEADDR, (
const void *)&optval,
sizeof(
int));
130 const char optval = 1;
131 setsockopt(m_socketFileDescriptor, SOL_SOCKET, SO_REUSEADDR, (
const char *)&optval,
sizeof(
int));
135 memset(&m_serverAddress, 0,
sizeof(m_serverAddress));
136 if (hostname.empty()) {
137 m_serverAddress.sin_family = AF_INET;
138 m_serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
139 m_serverAddress.sin_port = htons((
unsigned short)port);
141 std::stringstream ss;
143 struct addrinfo hints;
144 struct addrinfo *result = NULL;
145 struct addrinfo *ptr = NULL;
147 memset(&hints, 0,
sizeof(hints));
148 hints.ai_family = AF_INET;
149 hints.ai_socktype = SOCK_DGRAM;
150 hints.ai_protocol = IPPROTO_UDP;
152 DWORD dwRetval = getaddrinfo(hostname.c_str(), ss.str().c_str(), &hints, &result);
155 ss <<
"getaddrinfo failed with error: " << dwRetval;
159 for (ptr = result; ptr != NULL; ptr = ptr->ai_next) {
160 if (ptr->ai_family == AF_INET && ptr->ai_socktype == SOCK_DGRAM) {
161 m_serverAddress = *(
struct sockaddr_in *)ptr->ai_addr;
166 freeaddrinfo(result);
170 if (bind(m_socketFileDescriptor, (
struct sockaddr *)&m_serverAddress,
sizeof(m_serverAddress)) < 0)
173 m_clientLength =
sizeof(m_clientAddress);
189 std::string hostInfo =
"";
190 return receive(msg, hostInfo, timeoutMs);
209 FD_SET(m_socketFileDescriptor, &s);
210 struct timeval timeout;
212 timeout.tv_sec = timeoutMs / 1000;
213 timeout.tv_usec = (timeoutMs % 1000) * 1000;
215 int retval = select((
int)m_socketFileDescriptor + 1, &s, NULL, NULL, timeoutMs > 0 ? &timeout : NULL);
218 std::cerr <<
"Error select!" << std::endl;
224 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX 225 int length =
static_cast<int>(recvfrom(m_socketFileDescriptor, m_buf,
sizeof(m_buf), 0, (
struct sockaddr *)&m_clientAddress,
226 (socklen_t *)&m_clientLength));
229 recvfrom(m_socketFileDescriptor, m_buf,
sizeof(m_buf), 0, (
struct sockaddr *)&m_clientAddress, &m_clientLength);
232 return length < 0 ? -1 : 0;
235 msg = std::string(m_buf, length);
238 char hostname[NI_MAXHOST];
239 char servInfo[NI_MAXSERV];
240 DWORD dwRetval = getnameinfo((
struct sockaddr *)&m_clientAddress,
sizeof(
struct sockaddr), hostname, NI_MAXHOST,
241 servInfo, NI_MAXSERV, NI_NUMERICSERV);
243 std::string hostName =
"", hostIp =
"", hostPort =
"";
245 std::cerr <<
"getnameinfo failed with error: " << WSAGetLastError() << std::endl;
251 char result[INET_ADDRSTRLEN];
252 const char *ptr = inet_ntop(AF_INET, (
void *)&m_clientAddress.sin_addr, result,
sizeof(result));
254 std::cerr <<
"inet_ntop failed with error: " << WSAGetLastError() << std::endl;
259 std::stringstream ss;
260 ss << hostName <<
" " << hostIp <<
" " << hostPort;
282 if (msg.size() > VP_MAX_UDP_PAYLOAD) {
283 std::cerr <<
"Message is too long!" << std::endl;
288 memset(&m_clientAddress, 0,
sizeof(m_clientAddress));
289 std::stringstream ss;
291 struct addrinfo hints;
292 struct addrinfo *result = NULL;
293 struct addrinfo *ptr = NULL;
295 memset(&hints, 0,
sizeof(hints));
296 hints.ai_family = AF_INET;
297 hints.ai_socktype = SOCK_DGRAM;
298 hints.ai_protocol = IPPROTO_UDP;
300 DWORD dwRetval = getaddrinfo(hostname.c_str(), ss.str().c_str(), &hints, &result);
303 ss <<
"getaddrinfo failed with error: " << dwRetval;
307 for (ptr = result; ptr != NULL; ptr = ptr->ai_next) {
308 if (ptr->ai_family == AF_INET && ptr->ai_socktype == SOCK_DGRAM) {
309 m_clientAddress = *(
struct sockaddr_in *)ptr->ai_addr;
314 freeaddrinfo(result);
317 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX 318 return static_cast<int>(sendto(m_socketFileDescriptor, msg.c_str(), msg.size(), 0, (
struct sockaddr *)&m_clientAddress,
321 return sendto(m_socketFileDescriptor, msg.c_str(), (int)msg.size(), 0, (
struct sockaddr *)&m_clientAddress,
326 #elif !defined(VISP_BUILD_SHARED_LIBS) 328 void dummy_vpUDPServer(){};
error that can be emited by ViSP classes.
vpUDPServer(const int port)
int send(const std::string &msg, const std::string &hostname, const int port)
int receive(std::string &msg, const int timeoutMs=0)