rendered paste body#include "Socket.h"
#include "Common.h"
#include "ExceptionHandler.h"
#ifdef DEBUG
#include "Common.h"
#include "Configuration.h"
#endif
#pragma comment(lib,"wsock32.lib")
#ifndef MSG_WAITALL
// غير متأكد من السبب في ان يتم ذلك
#define MSG_WAITALL 0x08
#endif
Socket::Socket( LPCSTR serverName, u16_t port ) :
sock( INVALID_SOCKET ),
listener( false ),
currentPort( 0 )
{
if( !ConnectToServer( serverName, port ) )
ExceptionHandler::Throw( L"Error Socket::ConnectToServer (%i)", iWsaError );
}
Socket::Socket( SOCKET newSocket ) :
listener( false ),
currentPort( 0 )
{
setSocket( newSocket );
}
Socket::Socket( u16_t port ) :
sock( INVALID_SOCKET ),
listener( true ),
currentPort( 0 )
{
if( !CreateAsServer( port ) )
ExceptionHandler::Throw( L"Error Socket::CreateAsServer (%i)", iWsaError );
}
Socket::Socket() :
sock( INVALID_SOCKET ),
listener( false ),
currentPort( 0 )
{
}
Socket::~Socket()
{
Cleanup();
}
void Socket::RecordError()
{
iWsaError = WSAGetLastError();
}
bool Socket::WSAStartUp( WORD versionReq, LPWSADATA lpWsaData )
{
WSADATA wsaData;
if( !lpWsaData ) lpWsaData = &wsaData;
if( WSAStartup( versionReq, lpWsaData ) )
return false;
return true;
}
void Socket::setSocket( SOCKET newSocket )
{
Cleanup();
sock = newSocket;
listener = false;
}
SOCKET Socket::ExportSocket()
{
SOCKET tmpRet = sock;
sock = INVALID_SOCKET;
return tmpRet;
}
SOCKET Socket::getSocket()
{
return sock;
}
void Socket::Cleanup()
{
if( sock != INVALID_SOCKET ) closesocket( sock );
sock = INVALID_SOCKET;
}
bool Socket::isReadReady( DWORD dwSecondsToWait, DWORD dwMicrosecondsToWait )
{
timeval timeout = { dwSecondsToWait, dwMicrosecondsToWait };
int nfds;
fd_set read_fds;
FD_ZERO( &read_fds );
FD_SET( sock, &read_fds );
nfds = select( 0, &read_fds, NULL, NULL, &timeout );
if( nfds < 0 )
{
RecordError();
ExceptionHandler::Throw( L"Error Socket::select (%i)", iWsaError );
}
return (bool)(nfds > 0);
}
SOCKET Socket::getClientSocket( DWORD dwSecondsToWait, DWORD dwMicrosecondsToWait, sockaddr_in* newAddr )
{
if( !isReadReady( dwSecondsToWait, dwMicrosecondsToWait ) )
return INVALID_SOCKET;
sockaddr_in* newAddrPtr;
sockaddr_in lAddr;
newAddrPtr = newAddr ? newAddr : &lAddr;
int addrLen = sizeof( sockaddr_in );
return accept( sock, (sockaddr*)newAddrPtr, &addrLen );
}
bool Socket::Read( LPVOID inBuffer, DWORD maxLen, LPDWORD nbRead, bool flush )
{
int nBytes = recv( sock, (char*)inBuffer, maxLen, flush ? MSG_WAITALL : 0 );
if( nBytes <= 0 )
{
RecordError();
return false;
}
if( nbRead ) *nbRead = (DWORD)nBytes;
else if( flush && (DWORD)nBytes != maxLen ) return false; // If our option was to flush and we couldn't, then error
return true;
}
bool Socket::Write( LPVOID outBuffer, DWORD maxLen, LPDWORD nbWritten, bool flush )
{
DWORD totalWritten = 0;
do
{
int nBytes = send( sock, (char*)outBuffer + totalWritten, maxLen - totalWritten, 0 );
if( nBytes <= 0 )
{
RecordError();
return false;
}
totalWritten += (DWORD)nBytes;
} while( flush && totalWritten < maxLen );
if( nbWritten ) *nbWritten = totalWritten;
return true;
}
bool Socket::Close()
{
Cleanup();
return true;
}
bool Socket::CreateAsServer( u16_t port )
{
Cleanup();
sockaddr_in myAddr;
listener = true;
currentPort = port;
sock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
if( sock == INVALID_SOCKET )
{
RecordError();
return false;
}
myAddr.sin_addr.S_un.S_addr = INADDR_ANY;
myAddr.sin_family = AF_INET;
myAddr.sin_port = htons( port );
memset( &myAddr.sin_zero, 0, sizeof( myAddr.sin_zero ) );
if( bind( sock, (sockaddr*)&myAddr, sizeof(myAddr) ) == SOCKET_ERROR )
{
RecordError();
Cleanup();
return false;
}
if( listen( sock, SOMAXCONN ) == SOCKET_ERROR )
{
RecordError();
Cleanup();
return false;
}
return true;
}
bool Socket::ConnectToServer( LPCSTR serverName, u16_t port )
{
Cleanup();
listener = false;
currentPort = port;
sockaddr_in theirAddr;
hostent* host;
host = gethostbyname( serverName );
if( !host )
{
RecordError();
return false;
}
sock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
if( sock == INVALID_SOCKET )
{
RecordError();
return false;
}
theirAddr.sin_addr.S_un.S_addr = inet_addr( inet_ntoa( *(in_addr*)host->h_addr ) );
theirAddr.sin_family = AF_INET;
theirAddr.sin_port = htons( port );
memset( &theirAddr.sin_zero, 0, sizeof( theirAddr.sin_zero ) );
if( connect( sock, (sockaddr*)&theirAddr, sizeof( theirAddr ) ) == SOCKET_ERROR )
{
RecordError();
Cleanup();
return false;
}
return true;
}