diff options
Diffstat (limited to 'networksystem/udp_socket.cpp')
| -rw-r--r-- | networksystem/udp_socket.cpp | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/networksystem/udp_socket.cpp b/networksystem/udp_socket.cpp new file mode 100644 index 0000000..53f2fda --- /dev/null +++ b/networksystem/udp_socket.cpp @@ -0,0 +1,120 @@ +//========= 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; +} |