From 40e517594bbbd8196b55e6ae780e2739a8775b8a Mon Sep 17 00:00:00 2001 From: Bartosz Taudul Date: Mon, 17 Jun 2019 02:24:55 +0200 Subject: [PATCH] Add UDP broadcast socket. --- common/TracySocket.cpp | 78 ++++++++++++++++++++++++++++++++++++++++++ common/TracySocket.hpp | 20 +++++++++++ 2 files changed, 98 insertions(+) diff --git a/common/TracySocket.cpp b/common/TracySocket.cpp index 2ae7e8ce..2b61e897 100644 --- a/common/TracySocket.cpp +++ b/common/TracySocket.cpp @@ -345,4 +345,82 @@ void ListenSocket::Close() m_sock = -1; } +UdpBroadcast::UdpBroadcast() + : m_sock( -1 ) +{ +#ifdef _WIN32 + InitWinSock(); +#endif +} + +UdpBroadcast::~UdpBroadcast() +{ + if( m_sock != -1 ) Close(); +} + +bool UdpBroadcast::Open( const char* addr, const char* port ) +{ + assert( m_sock == -1 ); + + struct addrinfo hints; + struct addrinfo *res, *ptr; + + memset( &hints, 0, sizeof( hints ) ); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_DGRAM; + + if( getaddrinfo( addr, port, &hints, &res ) != 0 ) return false; + int sock = 0; + for( ptr = res; ptr; ptr = ptr->ai_next ) + { + if( ( sock = socket( ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol ) ) == -1 ) continue; +#if defined __APPLE__ + int val = 1; + setsockopt( sock, SOL_SOCKET, SO_NOSIGPIPE, &val, sizeof( val ) ); +#endif +#if defined _WIN32 || defined __CYGWIN__ + unsigned long broadcast = 1; + if( setsockopt( sock, SOL_SOCKET, SO_BROADCAST, (const char*)&broadcast, sizeof( broadcast ) ) == -1 ) +#else + int broadcast = 1; + if( setsockopt( sock, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof( broadcast ) ) == -1 ) +#endif + { +#ifdef _WIN32 + closesocket( sock ); +#else + close( sock ); +#endif + continue; + } + break; + } + freeaddrinfo( res ); + if( !ptr ) return false; + + m_sock = sock; + return true; +} + +void UdpBroadcast::Close() +{ + assert( m_sock != -1 ); +#ifdef _WIN32 + closesocket( m_sock ); +#else + close( m_sock ); +#endif + m_sock = -1; +} + +int UdpBroadcast::Send( const void* data, int len ) +{ + assert( m_sock != -1 ); + struct sockaddr_in addr; + addr.sin_family = AF_INET; + addr.sin_port = htons( 8087 ); + addr.sin_addr.s_addr = INADDR_BROADCAST; + return sendto( m_sock, (const char*)data, len, MSG_NOSIGNAL, (sockaddr*)&addr, sizeof( addr ) ); +} + } diff --git a/common/TracySocket.hpp b/common/TracySocket.hpp index 17fe22fd..dbd36005 100644 --- a/common/TracySocket.hpp +++ b/common/TracySocket.hpp @@ -63,6 +63,26 @@ private: int m_sock; }; +class UdpBroadcast +{ +public: + UdpBroadcast(); + ~UdpBroadcast(); + + bool Open( const char* addr, const char* port ); + void Close(); + + int Send( const void* data, int len ); + + UdpBroadcast( const UdpBroadcast& ) = delete; + UdpBroadcast( UdpBroadcast&& ) = delete; + UdpBroadcast& operator=( const UdpBroadcast& ) = delete; + UdpBroadcast& operator=( UdpBroadcast&& ) = delete; + +private: + int m_sock; +}; + } #endif