www.pudn.com > rDUNclientBeta1.zip > server.cpp


//rDUN Client - Server interface class 
//Copyright (C) Robert Merrison 2002  
 
//This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License  
//as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 
//This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied  
//warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 
//You should have received a copy of the GNU General Public License along with this program; if not, write to the  
//Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
#include "server.h" 
 
server_c::server_c() 
{ 
	connectSocket	= 0; 
	 
	memset( recvBuffer, 0, sizeof( recvBuffer )); 
	memset( sendBuffer, 0, sizeof( sendBuffer )); 
	memset( password, 0, sizeof( password )); 
 
	rConnectionState	= RCSTATE_UNKNOWN; 
	currentState		= STATE_DISCONNECTED; 
} 
 
server_c::~server_c() 
{ 
	closesocket( connectSocket ); 
	WSACleanup(); 
} 
 
bool server_c::connectTo( char* address, unsigned short port, HWND windowHandle, char* pword ) 
{ 
	if( !address ){ 
		return false; 
	} 
 
	if( pword ){ 
		strcpy( password, pword ); 
	} 
    	 
	if( currentState != STATE_DISCONNECTED ){ 
		disconnectFrom(); 
	} 
	 
	WSADATA winsockData; 
	if( WSAStartup ( 0x0202, &winsockData ) ){ 
		MessageBox( NULL, "Error in WSAStartup", "Error", MB_OK ); 
		return false; 
	} 
	connectSocket	= socket( AF_INET, SOCK_STREAM, 0 ); 
	 
	sockaddr_in connectAddr; 
	memset( &connectAddr, 0, sizeof( connectAddr )); 
	connectAddr.sin_family		= AF_INET; 
	connectAddr.sin_port		= htons( port ); 
	connectAddr.sin_addr.s_addr	= inet_addr( address ); 
 
	if( connect( connectSocket, (sockaddr*)&connectAddr, sizeof( connectAddr )) == SOCKET_ERROR ){ 
		MessageBox( NULL, "Error in connect", "Error", MB_OK ); 
		WSACleanup(); 
		return false; 
	} 
	linger lingerSettings; 
	lingerSettings.l_onoff	= 1; 
	lingerSettings.l_linger	= 0; 
	setsockopt( connectSocket, SOL_SOCKET, SO_LINGER, (char*)&lingerSettings, sizeof( lingerSettings )); 
	BOOL reuseAddrSetting = TRUE; 
	setsockopt( connectSocket, SOL_SOCKET, SO_REUSEADDR, (char*)&reuseAddrSetting, sizeof( reuseAddrSetting )); 
	appWindowHandle	= windowHandle; 
 
	WSAAsyncSelect( connectSocket, windowHandle, WM_ONSOCKET, ( FD_READ | FD_CLOSE | FD_WRITE )); 
	onConnect(); 
	return true; 
} 
 
void server_c::disconnectFrom() 
{ 
	if( connectSocket ){ 
		closesocket( connectSocket ); 
	} 
	rConnectionState	= RCSTATE_UNKNOWN; 
	currentState		= STATE_DISCONNECTED; 
	WSACleanup(); 
	return; 
} 
 
void server_c::onRead() 
{ 
	if( currentState == STATE_DISCONNECTED ){ 
		return; 
	} 
	char	data; 
	recv( connectSocket, &data, 1, 0 ); 
	 
	if( data == '\r' ){ 
		return; 
	} 
 
	if( data == '\n' ){ 
		processRecvBuffer(); 
		memset( recvBuffer, 0, sizeof( recvBuffer )); 
		return; 
	} 
 
	if( strlen( recvBuffer ) >= sizeof( recvBuffer )){ 
		memset( recvBuffer, 0, sizeof( recvBuffer )); 
	} 
	recvBuffer[strlen(recvBuffer)] = data; 
	recvBuffer[strlen(recvBuffer)+1] = '\0'; 
 
	return; 
} 
 
void server_c::onWrite() 
{ 
	MessageBox( NULL, "OnWrite", "In function", MB_OK ); 
	if( !connectSocket ){ 
		MessageBox( NULL, "Can't write data, not connected", "Error", MB_OK ); 
		return; 
	} 
 
	int bytesSent = send( connectSocket, sendBuffer, strlen( sendBuffer ), 0 ); 
	if( bytesSent != strlen( sendBuffer )){ 
		MessageBox( NULL, "Error, not all data sent or send error", "Error", MB_OK ); 
	} 
	else{ 
		MessageBox( NULL, sendBuffer, "Sent data", MB_OK ); 
	} 
	memset( sendBuffer, 0, sizeof( sendBuffer )); 
 
	return; 
} 
 
void server_c::onClose() 
{ 
	currentState		= STATE_DISCONNECTED; 
	rConnectionState	= RCSTATE_UNKNOWN; 
 
	shutdown( connectSocket, SD_BOTH );  
	closesocket( connectSocket ); 
	connectSocket	= 0; 
 
	memset( recvBuffer, 0, sizeof( recvBuffer )); 
	memset( sendBuffer, 0, sizeof( sendBuffer )); 
 
	return; 
} 
 
void server_c::onConnect() 
{ 
	currentState	= STATE_IDLE; 
} 
 
void server_c::rCConnect() 
{ 
	if( rConnectionState == RCSTATE_CONNECTED || rConnectionState == RCSTATE_CONNECTING ){ 
		return; 
	} 
 
	char message[64]; 
	memset( message, 0, sizeof( message )); 
	strcpy( message, "CONNECT" ); 
	sendData( message ); 
	return; 
} 
 
void server_c::rCDisconnect() 
{ 
	if( rConnectionState == RCSTATE_DISCONNECTED || rConnectionState == RCSTATE_DISCONNECTING ){ 
		return; 
	} 
	 
	char message[64]; 
	memset( message, 0, sizeof( message )); 
	strcpy( message, "DISCONNECT" ); 
	sendData( message ); 
	return; 
} 
 
void server_c::sendData( char* data) 
{ 
	strcat( data, "\r\n" ); 
 
	send( connectSocket, data, strlen( data ), 0 ); 
 
	return; 
} 
void server_c::processRecvBuffer() 
{ 
	if( stricmp( recvBuffer, "AUTH" ) == 0 ){ 
		currentState	= STATE_LOGIN; 
		sendData( password ); 
		return; 
	} 
 
	if( currentState == STATE_LOGIN && stricmp( recvBuffer, "OK" ) == 0 ){ 
		currentState	= STATE_PROTOCONFIRM; 
		char	ProtoVersionString[24]; 
		memset( ProtoVersionString, 0, sizeof( ProtoVersionString )); 
		sprintf( ProtoVersionString, "PROTOCOL %d", PROTOCOL_VERSION ); 
		sendData( ProtoVersionString ); 
		return; 
	} 
 
	if( currentState == STATE_PROTOCONFIRM && stricmp( recvBuffer, "GOODPROTOCOL" ) == 0 ){ 
		currentState	= STATE_IDLE; 
		return; 
	} 
 
	if( currentState == STATE_PROTOCONFIRM && stricmp( recvBuffer, "BADPROTOCOL" ) == 0 ){ 
		MessageBox( NULL, "Invalid protocol version", "Error", MB_OK ); 
		return; 
	} 
 
	if( stricmp( recvBuffer, "CONNECTED" ) == 0 ){ 
		rConnectionState	= RCSTATE_CONNECTED; 
		SendMessage( appWindowHandle, WM_RCSTATECHANGE, (WPARAM) rConnectionState, NULL ); 
		return; 
	} 
 
	if( stricmp( recvBuffer, "CONNECTING" ) == 0 ){ 
		rConnectionState	= RCSTATE_CONNECTING; 
		SendMessage( appWindowHandle, WM_RCSTATECHANGE, (WPARAM) rConnectionState, NULL ); 
		return; 
	} 
	 
	if( stricmp( recvBuffer, "DISCONNECTED" ) == 0 ){ 
		rConnectionState	= RCSTATE_DISCONNECTED; 
		SendMessage( appWindowHandle, WM_RCSTATECHANGE, (WPARAM) rConnectionState, NULL ); 
		return; 
	} 
 
	if( stricmp( recvBuffer, "DISCONNECTING" ) == 0 ){ 
		rConnectionState	= RCSTATE_DISCONNECTING; 
		SendMessage( appWindowHandle, WM_RCSTATECHANGE, (WPARAM) rConnectionState, NULL ); 
		return; 
	} 
	 
	if( stricmp( recvBuffer, "USERDISCONNECTED" ) == 0 ){ 
		rConnectionState	= RCSTATE_USERDISCONNECTED; 
		SendMessage( appWindowHandle, WM_RCSTATECHANGE, (WPARAM) rConnectionState, NULL ); 
		return; 
	} 
 
	if( stricmp( recvBuffer, "USERDISCONNECTING" ) == 0 ){ 
		rConnectionState	= RCSTATE_USERDISCONNECTING; 
		SendMessage( appWindowHandle, WM_RCSTATECHANGE, (WPARAM) rConnectionState, NULL ); 
		return; 
	} 
	return; 
}