All pastes #2074826 Raw Edit

Mine

public text v1 · immutable
#2074826 ·published 2011-06-05 02:24 UTC
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;
}