|
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//===========================================================================//
#include <winsock.h>
#include "udp_socket.h"
#include "tier1/utlbuffer.h"
#include "tier1/strtools.h"
class CUDPSocket::CImpl { public: struct sockaddr_in m_SocketIP; };
CUDPSocket::CUDPSocket( ) : m_socketIP(), m_Socket( INVALID_SOCKET ), m_Port( 0 ), m_pImpl( new CImpl ) { Q_memset( &m_socketIP, 0, sizeof( m_socketIP ) ); }
CUDPSocket::~CUDPSocket() { delete m_pImpl; }
bool CUDPSocket::Init( unsigned short nBindToPort ) { m_Port = nBindToPort; 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; address.sin_family = AF_INET; address.sin_port = htons( m_Port ); address.sin_addr.S_un.S_addr = INADDR_ANY;
if ( SOCKET_ERROR == bind( m_Socket, ( struct sockaddr * )&address, sizeof( address ) ) ) { return false; }
// Set to non-blocking i/o
unsigned long value = 1; if ( SOCKET_ERROR == ioctlsocket( m_Socket, FIONBIO, &value ) ) { return false; }
return true; }
void CUDPSocket::Shutdown() { if ( m_Socket != INVALID_SOCKET ) { closesocket( static_cast<unsigned int>( m_Socket )); } }
bool CUDPSocket::RecvFrom( netadr_t& packet_from, CUtlBuffer& data ) { sockaddr from; int nFromLen = sizeof( from );
int nMaxBytesToRead = data.Size() - data.TellPut(); char *pBuffer = (char*)data.PeekPut();
int nBytesRead = recvfrom( m_Socket, pBuffer, nMaxBytesToRead, 0, &from, &nFromLen ); if ( nBytesRead == SOCKET_ERROR ) { int nError = WSAGetLastError(); if ( nError != WSAEWOULDBLOCK ) { Warning( "Socket error '%i'\n", nError ); } return false; }
packet_from.SetFromSockadr( &from ); data.SeekPut( CUtlBuffer::SEEK_CURRENT, nBytesRead ); return true; }
bool CUDPSocket::SendTo( const netadr_t &recipient, const CUtlBuffer& data ) { return SendTo( recipient, (const byte *)data.Base(), (size_t)data.TellPut() ); }
bool CUDPSocket::SendTo( const netadr_t &recipient, const byte *data, size_t datalength ) { sockaddr dest; recipient.ToSockadr( &dest );
// Send data
int bytesSent = sendto ( m_Socket, (const char *)data, (int)datalength, 0, reinterpret_cast< const sockaddr * >( &dest ), sizeof( dest ) );
if ( SOCKET_ERROR == bytesSent ) { return false; }
return true; }
|