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;
}