Initial commit.
This commit is contained in:
432
codemp/xbox/xbsocket.cpp
Normal file
432
codemp/xbox/xbsocket.cpp
Normal file
@@ -0,0 +1,432 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// File: XbSocket.cpp
|
||||
//
|
||||
// Desc: Wraps SOCKET object
|
||||
//
|
||||
// Hist: 05.17.01 - New for June XDK release
|
||||
// 08.08.01 - Moved to common framework
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "XbSocket.h"
|
||||
#include <cassert>
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: CXBSocket()
|
||||
// Desc: Associate existing socket with object. Object will close the socket
|
||||
// when it is destroyed.
|
||||
//-----------------------------------------------------------------------------
|
||||
CXBSocket::CXBSocket( SOCKET sock )
|
||||
:
|
||||
m_Socket( sock )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: CXBSocket()
|
||||
// Desc: Create a socket of the given type
|
||||
//-----------------------------------------------------------------------------
|
||||
CXBSocket::CXBSocket( SocketType type )
|
||||
:
|
||||
m_Socket( INVALID_SOCKET )
|
||||
{
|
||||
BOOL bSuccess = Open( type );
|
||||
assert( bSuccess );
|
||||
(VOID)bSuccess;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: CXBSocket()
|
||||
// Desc: Create a socket of the given type/protocol
|
||||
//-----------------------------------------------------------------------------
|
||||
CXBSocket::CXBSocket( INT iType, INT iProtocol )
|
||||
:
|
||||
m_Socket( INVALID_SOCKET )
|
||||
{
|
||||
BOOL bSuccess = Open( iType, iProtocol );
|
||||
assert( bSuccess );
|
||||
(VOID)bSuccess;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: ~CXBSocket()
|
||||
// Desc: Close and release socket
|
||||
//-----------------------------------------------------------------------------
|
||||
CXBSocket::~CXBSocket()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: Open()
|
||||
// Desc: Open a socket of the given type
|
||||
//-----------------------------------------------------------------------------
|
||||
BOOL CXBSocket::Open( SocketType type )
|
||||
{
|
||||
switch( type )
|
||||
{
|
||||
case Type_UDP:
|
||||
return Open( SOCK_DGRAM, IPPROTO_UDP );
|
||||
|
||||
case Type_TCP:
|
||||
return Open( SOCK_STREAM, IPPROTO_TCP );
|
||||
|
||||
default:
|
||||
assert( type == Type_VDP );
|
||||
return Open( SOCK_DGRAM, IPPROTO_VDP );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: Open()
|
||||
// Desc: Open a socket of the given type/protocol
|
||||
//-----------------------------------------------------------------------------
|
||||
BOOL CXBSocket::Open( INT iType, INT iProtocol )
|
||||
{
|
||||
Close();
|
||||
m_Socket = socket( AF_INET, iType, iProtocol );
|
||||
return( m_Socket != INVALID_SOCKET );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: IsOpen()
|
||||
// Desc: TRUE if socket is open
|
||||
//-----------------------------------------------------------------------------
|
||||
BOOL CXBSocket::IsOpen() const
|
||||
{
|
||||
return( m_Socket != INVALID_SOCKET );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: Close()
|
||||
// Desc: Close socket
|
||||
//-----------------------------------------------------------------------------
|
||||
INT CXBSocket::Close()
|
||||
{
|
||||
INT iResult = 0;
|
||||
if( m_Socket != INVALID_SOCKET )
|
||||
{
|
||||
iResult = closesocket( m_Socket );
|
||||
m_Socket = INVALID_SOCKET;
|
||||
}
|
||||
return iResult;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: Accept()
|
||||
// Desc: Permit incoming connection attempt
|
||||
//-----------------------------------------------------------------------------
|
||||
SOCKET CXBSocket::Accept( SOCKADDR_IN* pSockAddr )
|
||||
{
|
||||
assert( m_Socket != INVALID_SOCKET );
|
||||
INT iSize = sizeof( SOCKADDR_IN );
|
||||
|
||||
SOCKET sockResult = accept( m_Socket, (sockaddr*)(pSockAddr), &iSize );
|
||||
|
||||
if( sockResult != INVALID_SOCKET && pSockAddr != NULL )
|
||||
assert( iSize == sizeof( SOCKADDR_IN ) );
|
||||
return sockResult;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: Bind()
|
||||
// Desc: Associate local address with socket
|
||||
//-----------------------------------------------------------------------------
|
||||
INT CXBSocket::Bind( const SOCKADDR_IN* pSockAddr )
|
||||
{
|
||||
assert( m_Socket != INVALID_SOCKET );
|
||||
assert( pSockAddr != NULL );
|
||||
assert( pSockAddr->sin_family == AF_INET );
|
||||
|
||||
INT iResult = bind( m_Socket, (const sockaddr*)(pSockAddr),
|
||||
sizeof( SOCKADDR_IN ) );
|
||||
return iResult;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: Connect()
|
||||
// Desc: Connect socket
|
||||
//-----------------------------------------------------------------------------
|
||||
INT CXBSocket::Connect( const SOCKADDR_IN* pSockAddr )
|
||||
{
|
||||
assert( m_Socket != INVALID_SOCKET );
|
||||
assert( pSockAddr != NULL );
|
||||
assert( pSockAddr->sin_family == AF_INET );
|
||||
|
||||
INT iResult = connect( m_Socket, (const sockaddr*)(pSockAddr),
|
||||
sizeof( SOCKADDR_IN ) );
|
||||
return iResult;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: GetSocket()
|
||||
// Desc: Returns the socket handle
|
||||
//-----------------------------------------------------------------------------
|
||||
SOCKET CXBSocket::GetSocket() const
|
||||
{
|
||||
return m_Socket;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: GetSockName()
|
||||
// Desc: Get socket "name"
|
||||
//-----------------------------------------------------------------------------
|
||||
INT CXBSocket::GetSockName( SOCKADDR_IN* pSockAddr ) const
|
||||
{
|
||||
assert( m_Socket != INVALID_SOCKET );
|
||||
assert( pSockAddr != NULL );
|
||||
INT iSize = sizeof( SOCKADDR_IN );
|
||||
|
||||
INT iResult = getsockname( m_Socket, (sockaddr*)(pSockAddr), &iSize );
|
||||
|
||||
if( iResult != SOCKET_ERROR )
|
||||
assert( iSize == sizeof( SOCKADDR_IN ) );
|
||||
return iResult;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: GetSockOpt()
|
||||
// Desc: Get socket option
|
||||
//-----------------------------------------------------------------------------
|
||||
INT CXBSocket::GetSockOpt( INT iLevel, INT iName, VOID* pValue, INT* piSize ) const
|
||||
{
|
||||
assert( m_Socket != INVALID_SOCKET );
|
||||
assert( pValue != NULL );
|
||||
assert( piSize != NULL );
|
||||
|
||||
INT iResult = getsockopt( m_Socket, iLevel, iName, (CHAR*)(pValue), piSize );
|
||||
return iResult;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: IoCtlSocket()
|
||||
// Desc: Configure socket I/O mode
|
||||
//-----------------------------------------------------------------------------
|
||||
INT CXBSocket::IoCtlSocket( LONG nCmd, DWORD* pArg )
|
||||
{
|
||||
assert( m_Socket != INVALID_SOCKET );
|
||||
assert( pArg != NULL );
|
||||
|
||||
INT iResult = ioctlsocket( m_Socket, nCmd, pArg );
|
||||
return iResult;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: Listen()
|
||||
// Desc: Listen for incoming connection
|
||||
//-----------------------------------------------------------------------------
|
||||
INT CXBSocket::Listen( INT iBacklog )
|
||||
{
|
||||
assert( m_Socket != INVALID_SOCKET );
|
||||
|
||||
INT iResult = listen( m_Socket, iBacklog );
|
||||
return iResult;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: Recv()
|
||||
// Desc: Receive data on socket
|
||||
//-----------------------------------------------------------------------------
|
||||
INT CXBSocket::Recv( VOID* pBuffer, INT iBytes )
|
||||
{
|
||||
assert( m_Socket != INVALID_SOCKET );
|
||||
assert( pBuffer != NULL );
|
||||
assert( iBytes >= 0 );
|
||||
|
||||
INT iResult = recv( m_Socket, (CHAR*)(pBuffer), iBytes, 0 );
|
||||
return iResult;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: RecvFrom()
|
||||
// Desc: Receive data on socket and report source address
|
||||
//-----------------------------------------------------------------------------
|
||||
INT CXBSocket::RecvFrom( VOID* pBuffer, INT iBytes, SOCKADDR_IN* pSockAddr )
|
||||
{
|
||||
assert( m_Socket != INVALID_SOCKET );
|
||||
assert( pBuffer != NULL );
|
||||
assert( iBytes >= 0 );
|
||||
INT iSize = sizeof( SOCKADDR_IN );
|
||||
|
||||
INT iResult = recvfrom( m_Socket, (CHAR*)(pBuffer), iBytes, 0,
|
||||
(sockaddr*)(pSockAddr), &iSize );
|
||||
if( iResult != SOCKET_ERROR && pSockAddr != NULL )
|
||||
assert( iSize == sizeof( SOCKADDR_IN ) );
|
||||
|
||||
return iResult;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: Select()
|
||||
// Desc: Does a select call to check status of socket - returns separate
|
||||
// BOOLs for read, write, and error
|
||||
//-----------------------------------------------------------------------------
|
||||
INT CXBSocket::Select( BOOL* pbRead, BOOL* pbWrite, BOOL* pbError )
|
||||
{
|
||||
assert( m_Socket != INVALID_SOCKET );
|
||||
|
||||
INT iResultTotal = 0;
|
||||
|
||||
timeval tv = {0};
|
||||
if( pbRead )
|
||||
{
|
||||
fd_set fdsRead = {0};
|
||||
FD_SET( m_Socket, &fdsRead );
|
||||
|
||||
INT iResult = select( 0, &fdsRead, NULL, NULL, &tv );
|
||||
assert( iResult != SOCKET_ERROR );
|
||||
|
||||
*pbRead = ( iResult == 1 );
|
||||
iResultTotal += iResult;
|
||||
}
|
||||
|
||||
if( pbWrite )
|
||||
{
|
||||
fd_set fdsWrite = {0};
|
||||
FD_SET( m_Socket, &fdsWrite );
|
||||
|
||||
INT iResult = select( 0, NULL, &fdsWrite, NULL, &tv );
|
||||
assert( iResult != SOCKET_ERROR );
|
||||
|
||||
*pbWrite = ( iResult == 1 );
|
||||
iResultTotal += iResult;
|
||||
}
|
||||
|
||||
if( pbError )
|
||||
{
|
||||
fd_set fdsError = {0};
|
||||
FD_SET( m_Socket, &fdsError );
|
||||
|
||||
INT iResult = select( 0, NULL, NULL, &fdsError, &tv );
|
||||
assert( iResult != SOCKET_ERROR );
|
||||
|
||||
*pbError = ( iResult == 1 );
|
||||
iResultTotal += iResult;
|
||||
}
|
||||
|
||||
return iResultTotal;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: Send()
|
||||
// Desc: Send data on socket
|
||||
//-----------------------------------------------------------------------------
|
||||
INT CXBSocket::Send( const VOID* pBuffer, INT iBytes )
|
||||
{
|
||||
assert( m_Socket != INVALID_SOCKET );
|
||||
assert( pBuffer != NULL );
|
||||
assert( iBytes >= 0 );
|
||||
|
||||
INT iResult = send( m_Socket, (const CHAR*)(pBuffer), iBytes, 0 );
|
||||
return iResult;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: SendTo()
|
||||
// Desc: Send data on socket to specific destination
|
||||
//-----------------------------------------------------------------------------
|
||||
INT CXBSocket::SendTo( const VOID* pBuffer, INT iBytes, const SOCKADDR_IN* pSockAddr )
|
||||
{
|
||||
assert( m_Socket != INVALID_SOCKET );
|
||||
assert( pBuffer != NULL );
|
||||
assert( iBytes >= 0 );
|
||||
|
||||
INT iResult = sendto( m_Socket, (const CHAR*)(pBuffer), iBytes, 0,
|
||||
(const sockaddr*)(pSockAddr), sizeof( SOCKADDR_IN ) );
|
||||
return iResult;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: SetSockOpt()
|
||||
// Desc: Set socket option
|
||||
//-----------------------------------------------------------------------------
|
||||
INT CXBSocket::SetSockOpt( INT iLevel, INT iName, const VOID* pValue, INT iBytes )
|
||||
{
|
||||
assert( m_Socket != INVALID_SOCKET );
|
||||
assert( pValue != NULL );
|
||||
|
||||
INT iResult = setsockopt( m_Socket, iLevel, iName, (const CHAR*)(pValue),
|
||||
iBytes );
|
||||
return iResult;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: Shutdown()
|
||||
// Desc: Disabled sending and/or receiving on socket
|
||||
//-----------------------------------------------------------------------------
|
||||
INT CXBSocket::Shutdown( INT iHow )
|
||||
{
|
||||
assert( m_Socket != INVALID_SOCKET );
|
||||
|
||||
INT iResult = shutdown( m_Socket, iHow );
|
||||
return iResult;
|
||||
}
|
||||
Reference in New Issue
Block a user