From 39ed87570bdb2f86969d4be821c94b722dc71179 Mon Sep 17 00:00:00 2001 From: Joe Ludwig Date: Wed, 26 Jun 2013 15:22:04 -0700 Subject: First version of the SOurce SDK 2013 --- mp/src/public/blockingudpsocket.cpp | 150 ++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 mp/src/public/blockingudpsocket.cpp (limited to 'mp/src/public/blockingudpsocket.cpp') diff --git a/mp/src/public/blockingudpsocket.cpp b/mp/src/public/blockingudpsocket.cpp new file mode 100644 index 00000000..01db58fc --- /dev/null +++ b/mp/src/public/blockingudpsocket.cpp @@ -0,0 +1,150 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#if defined(_WIN32) && !defined(_X360) +#include +#elif POSIX +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#include +#include +#include +#include +#define closesocket close +#endif + +#include "blockingudpsocket.h" +#include "tier0/vcrmode.h" + +class CBlockingUDPSocket::CImpl +{ +public: + struct sockaddr_in m_SocketIP; + fd_set m_FDSet; +}; + +CBlockingUDPSocket::CBlockingUDPSocket() : + m_cserIP(), + m_Socket( 0 ), + m_pImpl( new CImpl ) +{ + CreateSocket(); +} + +CBlockingUDPSocket::~CBlockingUDPSocket() +{ + delete m_pImpl; + closesocket( static_cast( m_Socket )); +} + +bool CBlockingUDPSocket::CreateSocket (void) +{ + struct sockaddr_in address; + + m_Socket = socket( PF_INET, SOCK_DGRAM, IPPROTO_UDP ); + if ( m_Socket == INVALID_SOCKET ) + { + return false; + } + + address = m_pImpl->m_SocketIP; + + if ( SOCKET_ERROR == bind( m_Socket, ( struct sockaddr * )&address, sizeof( address ) ) ) + { + return false; + } + +#ifdef _WIN32 + if ( m_pImpl->m_SocketIP.sin_addr.S_un.S_addr == INADDR_ANY ) + { + m_pImpl->m_SocketIP.sin_addr.S_un.S_addr = 0L; + } +#elif POSIX + if ( m_pImpl->m_SocketIP.sin_addr.s_addr == INADDR_ANY ) + { + m_pImpl->m_SocketIP.sin_addr.s_addr = 0L; + } +#endif + + return true; +} + +bool CBlockingUDPSocket::WaitForMessage( float timeOutInSeconds ) +{ + struct timeval tv; + + FD_ZERO( &m_pImpl->m_FDSet ); + FD_SET( m_Socket, &m_pImpl->m_FDSet );//lint !e717 + + tv.tv_sec = (int)timeOutInSeconds; + float remainder = timeOutInSeconds - (int)timeOutInSeconds; + tv.tv_usec = (int)( remainder * 1000000 + 0.5f ); /* micro seconds */ + + if ( SOCKET_ERROR == select( ( int )m_Socket + 1, &m_pImpl->m_FDSet, NULL, NULL, &tv ) ) + { + return false; + } + + if ( FD_ISSET( m_Socket, &m_pImpl->m_FDSet) ) + { + return true; + } + + // Timed out + return false; +} + +unsigned int CBlockingUDPSocket::ReceiveSocketMessage( struct sockaddr_in *packet_from, unsigned char *buf, size_t bufsize ) +{ + memset( packet_from, 0, sizeof( *packet_from ) ); + + struct sockaddr fromaddress; + int fromlen = sizeof( fromaddress ); + + int packet_length = VCRHook_recvfrom + ( + m_Socket, + (char *)buf, + (int)bufsize, + 0, + &fromaddress, + &fromlen + ); + + if ( SOCKET_ERROR == packet_length ) + { + return 0; + } + + // In case it's parsed as a string + buf[ packet_length ] = 0; + + // Copy over the receive address + *packet_from = *( struct sockaddr_in * )&fromaddress; + + return ( unsigned int )packet_length; +} + +bool CBlockingUDPSocket::SendSocketMessage( const struct sockaddr_in & rRecipient, const unsigned char *buf, size_t bufsize ) +{ + // Send data + int bytesSent = sendto + ( + m_Socket, + (const char *)buf, + (int)bufsize, + 0, + reinterpret_cast< const sockaddr * >( &rRecipient ), + sizeof( rRecipient ) + ); + + if ( SOCKET_ERROR == bytesSent ) + { + return false; + } + + return true; +} -- cgit v1.2.3