aboutsummaryrefslogtreecommitdiff
path: root/sp/src/public/blockingudpsocket.cpp
diff options
context:
space:
mode:
authorJoe Ludwig <[email protected]>2013-06-26 15:22:04 -0700
committerJoe Ludwig <[email protected]>2013-06-26 15:22:04 -0700
commit39ed87570bdb2f86969d4be821c94b722dc71179 (patch)
treeabc53757f75f40c80278e87650ea92808274aa59 /sp/src/public/blockingudpsocket.cpp
downloadsource-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.tar.xz
source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.zip
First version of the SOurce SDK 2013
Diffstat (limited to 'sp/src/public/blockingudpsocket.cpp')
-rw-r--r--sp/src/public/blockingudpsocket.cpp150
1 files changed, 150 insertions, 0 deletions
diff --git a/sp/src/public/blockingudpsocket.cpp b/sp/src/public/blockingudpsocket.cpp
new file mode 100644
index 00000000..01db58fc
--- /dev/null
+++ b/sp/src/public/blockingudpsocket.cpp
@@ -0,0 +1,150 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#if defined(_WIN32) && !defined(_X360)
+#include <winsock.h>
+#elif POSIX
+#define INVALID_SOCKET -1
+#define SOCKET_ERROR -1
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <unistd.h>
+#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<unsigned int>( 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;
+}