digitalpacman
Programmer
I'm currently learning how to create servers and clients for gaming purposes. I wrote a simple program which acts as either server or client. It uses multithreading for the login part of the server so that it can listen while running the program, basic heh. The error is that sometimes I get a "Unhandled handle" error, which seems to have gone away but now the server shuts down after 2 people connect to the server.
// Standard Includes
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
#include <SocketObject.h>
#include <apvector.h>
void vServerConnection( int iListenPort );
void vClientConnection( char *szServerIP, int iServerListenPort );
void thrClientsThread(SocketObject *sm);
SocketObject ClientSocketObject[10];
SocketObject ServerSocketObject; // Server Socket Object
// Mutex handle
HANDLE g_hCreditMutex;
int clients = -1;
struct stChatPacket
{
stPacketHeader stHeader;
char szChatMessage[128];
};
//
// ----> Main Program Function (REQUIRED)
//
int main( int argc, char *argv[] )
{
g_hCreditMutex = CreateMutex(
NULL,
0,
"Credit Mutex"
);
if( argc < 3 ) {
return( 0 );
}
if( !stricmp( argv[1], "server" ) )
vServerConnection( atoi( argv[2] ) );
else
vClientConnection( argv[2], atoi( argv[3] ) );
return( 1 );
}
// Function for server
void vServerConnection( int iListenPort )
{
SocketObject ClientSObject; // Server Socket Object
DWORD dwCreditsID;
HANDLE hClientsThreadHandle;
char DataPacket[128]; // Data Packet to Transmit
int iBytesReceived = 0; // # of Bytes Received
int iBytesSent = 0;
stChatPacket ChatPacket;
char szPacketBuffer[32768];
cout << "<Server> Attempting to listen on Port " << iListenPort << endl;
// Attempt to start the server
if ( ServerSocketObject.Bind( iListenPort ) )
{
hClientsThreadHandle = CreateThread(
NULL, // Security, default is ok
NULL, // Initial stack size, default ok
(LPTHREAD_START_ROUTINE ) &thrClientsThread, // The thread function
&ClientSocketObject, // Data to pass to the function
NULL, // Creation flags, keep NULL
&dwCreditsID // Identifier (we dont use this)
);
// Loop forever or until a break is issued
char szTempChar;
while (1)
{
while( !_kbhit() )
{
WaitForSingleObject( g_hCreditMutex, INFINITE );
// Check for incomming data
for ( int a = 0; a <= clients; ++a )
{
iBytesReceived = ClientSocketObject[a].vGetPacket(szPacketBuffer);
if( iBytesReceived > 0 )
{
// Copy the received data into the chat packet
memcpy(&ChatPacket,szPacketBuffer,sizeof(ChatPacket));
strcpy(DataPacket,ChatPacket.szChatMessage);
cout << endl << "<Client> " << DataPacket << endl;
printf("<Server> "
}
}
ReleaseMutex( g_hCreditMutex );
}
szTempChar = getche();
if( szTempChar == 13 )
break;
}
// Disconnect the client
for ( int a = 0; a <= clients; ++a )
{
ClientSocketObject[a].Disconnect();
}
cout << "<Server> Clients Disconnected" << endl;
}
else {
cout << "<Server> Failed to Listen" << endl;
}
CloseHandle( g_hCreditMutex );
CloseHandle( hClientsThreadHandle );
}
// Function for client
void vClientConnection( char *szServerIP, int iServerListenPort )
{
SocketObject ClientSObject; // Server Socket Object
char szTempChar;
int iBytesSent;
cout << "<Client> Connecting to " << szServerIP << ", Port " << iServerListenPort << endl;
// Connect to the IP and Port
if( ClientSObject.Connect( szServerIP, iServerListenPort ) )
{
while (true)
{
while ( !_kbhit() )
{
iBytesSent = ClientSObject.Send("Testing",128,0);
}
szTempChar = getche();
if( szTempChar == 13 )
break;
}
}
// Disconnect from the server
ClientSObject.Disconnect();
}
void thrClientsThread( SocketObject *sm )
{
// Loop until we are told to quit
while( 1 )
{
ServerSocketObject.Listen();
WaitForSingleObject( g_hCreditMutex, INFINITE );
clients += 1;
ServerSocketObject.Accept( sm[ clients ] );
cout << "<Server> Client Connected to Port " << 6000 << "; ID: " << clients << endl;
ReleaseMutex( g_hCreditMutex );
}
}
// Standard Includes
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
#include <SocketObject.h>
#include <apvector.h>
void vServerConnection( int iListenPort );
void vClientConnection( char *szServerIP, int iServerListenPort );
void thrClientsThread(SocketObject *sm);
SocketObject ClientSocketObject[10];
SocketObject ServerSocketObject; // Server Socket Object
// Mutex handle
HANDLE g_hCreditMutex;
int clients = -1;
struct stChatPacket
{
stPacketHeader stHeader;
char szChatMessage[128];
};
//
// ----> Main Program Function (REQUIRED)
//
int main( int argc, char *argv[] )
{
g_hCreditMutex = CreateMutex(
NULL,
0,
"Credit Mutex"
);
if( argc < 3 ) {
return( 0 );
}
if( !stricmp( argv[1], "server" ) )
vServerConnection( atoi( argv[2] ) );
else
vClientConnection( argv[2], atoi( argv[3] ) );
return( 1 );
}
// Function for server
void vServerConnection( int iListenPort )
{
SocketObject ClientSObject; // Server Socket Object
DWORD dwCreditsID;
HANDLE hClientsThreadHandle;
char DataPacket[128]; // Data Packet to Transmit
int iBytesReceived = 0; // # of Bytes Received
int iBytesSent = 0;
stChatPacket ChatPacket;
char szPacketBuffer[32768];
cout << "<Server> Attempting to listen on Port " << iListenPort << endl;
// Attempt to start the server
if ( ServerSocketObject.Bind( iListenPort ) )
{
hClientsThreadHandle = CreateThread(
NULL, // Security, default is ok
NULL, // Initial stack size, default ok
(LPTHREAD_START_ROUTINE ) &thrClientsThread, // The thread function
&ClientSocketObject, // Data to pass to the function
NULL, // Creation flags, keep NULL
&dwCreditsID // Identifier (we dont use this)
);
// Loop forever or until a break is issued
char szTempChar;
while (1)
{
while( !_kbhit() )
{
WaitForSingleObject( g_hCreditMutex, INFINITE );
// Check for incomming data
for ( int a = 0; a <= clients; ++a )
{
iBytesReceived = ClientSocketObject[a].vGetPacket(szPacketBuffer);
if( iBytesReceived > 0 )
{
// Copy the received data into the chat packet
memcpy(&ChatPacket,szPacketBuffer,sizeof(ChatPacket));
strcpy(DataPacket,ChatPacket.szChatMessage);
cout << endl << "<Client> " << DataPacket << endl;
printf("<Server> "
}
}
ReleaseMutex( g_hCreditMutex );
}
szTempChar = getche();
if( szTempChar == 13 )
break;
}
// Disconnect the client
for ( int a = 0; a <= clients; ++a )
{
ClientSocketObject[a].Disconnect();
}
cout << "<Server> Clients Disconnected" << endl;
}
else {
cout << "<Server> Failed to Listen" << endl;
}
CloseHandle( g_hCreditMutex );
CloseHandle( hClientsThreadHandle );
}
// Function for client
void vClientConnection( char *szServerIP, int iServerListenPort )
{
SocketObject ClientSObject; // Server Socket Object
char szTempChar;
int iBytesSent;
cout << "<Client> Connecting to " << szServerIP << ", Port " << iServerListenPort << endl;
// Connect to the IP and Port
if( ClientSObject.Connect( szServerIP, iServerListenPort ) )
{
while (true)
{
while ( !_kbhit() )
{
iBytesSent = ClientSObject.Send("Testing",128,0);
}
szTempChar = getche();
if( szTempChar == 13 )
break;
}
}
// Disconnect from the server
ClientSObject.Disconnect();
}
void thrClientsThread( SocketObject *sm )
{
// Loop until we are told to quit
while( 1 )
{
ServerSocketObject.Listen();
WaitForSingleObject( g_hCreditMutex, INFINITE );
clients += 1;
ServerSocketObject.Accept( sm[ clients ] );
cout << "<Server> Client Connected to Port " << 6000 << "; ID: " << clients << endl;
ReleaseMutex( g_hCreditMutex );
}
}