/******************************************************************************* * Copyright (c) 2021 Nerian Vision GmbH * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. *******************************************************************************/ /******************************************************************************* * This header file contains include statements and definitions for simplifying * cross platform network development *******************************************************************************/ #ifndef VISIONTRANSFER_NETWORKING_H #define VISIONTRANSFER_NETWORKING_H // Network headers #ifdef _WIN32 #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x501 #endif #define _WINSOCK_DEPRECATED_NO_WARNINGS #ifndef NOMINMAX #define NOMINMAX #endif #include #include #include #include #include #include #include // Some defines to make windows socket look more like // posix sockets. #ifdef EWOULDBLOCK #undef EWOULDBLOCK #endif #ifdef ECONNRESET #undef ECONNRESET #endif #ifdef ETIMEDOUT #undef ETIMEDOUT #endif #ifdef EPIPE #undef EPIPE #endif #define EWOULDBLOCK WSAEWOULDBLOCK #define ECONNRESET WSAECONNRESET #define ETIMEDOUT WSAETIMEDOUT #define EPIPE WSAECONNABORTED #define MSG_DONTWAIT 0 #define SHUT_WR SD_BOTH inline int close(SOCKET s) { return closesocket(s); } // Emulate posix errno. Does not work in a throw // statement (WTF?) #undef errno #define errno WSAGetLastError() #define strerror win_strerror // Visual studio does not come with snprintf #ifndef snprintf #define snprintf _snprintf_s #endif inline std::string win_strerror(unsigned long error) { char* str = nullptr; if(FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&str, 0, nullptr) == 0 || str == nullptr) { return "Unknown error"; } else { char buffer[512]; snprintf(buffer, sizeof(buffer), "%s (%lu)", str, error); LocalFree(str); return std::string(buffer); } } typedef int socklen_t; #else #include #include #include #include #include #include #include #include #include #include #include #include // Unfortunately we have to use a winsock like socket type typedef int SOCKET; #define INVALID_SOCKET -1 // Also we need some additional winsock defines #define WSA_IO_PENDING 0 #define WSAECONNRESET 0 #endif namespace visiontransfer { namespace internal { /** * \brief A collection of helper functions for implementing network communication. */ class Networking { public: static void initNetworking(); static addrinfo* resolveAddress(const char* address, const char* service); static SOCKET connectTcpSocket(const addrinfo* address); static void setSocketTimeout(SOCKET socket, int timeoutMillisec); static void closeSocket(SOCKET& socket); static void setSocketBlocking(SOCKET socket, bool blocking); static void enableReuseAddress(SOCKET socket, bool reuse); static void bindSocket(SOCKET socket, const addrinfo* addressInfo); static SOCKET acceptConnection(SOCKET socket, sockaddr_in& remoteAddress); }; }} // namespace #endif