mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-08 01:39:36 +00:00
1
This commit is contained in:
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user