summaryrefslogtreecommitdiff
path: root/networksystem/udp_socket.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'networksystem/udp_socket.cpp')
-rw-r--r--networksystem/udp_socket.cpp120
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;
+}