Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Threading for multi-client server

Status
Not open for further replies.

digitalpacman

Programmer
Apr 4, 2003
17
US
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,
&quot;Credit Mutex&quot;
);

if( argc < 3 ) {
return( 0 );
}

if( !stricmp( argv[1], &quot;server&quot; ) )
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 << &quot;<Server> Attempting to listen on Port &quot; << 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 << &quot;<Client> &quot; << DataPacket << endl;
printf(&quot;<Server> &quot;);
}
}
ReleaseMutex( g_hCreditMutex );
}
szTempChar = getche();
if( szTempChar == 13 )
break;
}
// Disconnect the client
for ( int a = 0; a <= clients; ++a )
{
ClientSocketObject[a].Disconnect();
}

cout << &quot;<Server> Clients Disconnected&quot; << endl;
}
else {
cout << &quot;<Server> Failed to Listen&quot; << 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 << &quot;<Client> Connecting to &quot; << szServerIP << &quot;, Port &quot; << iServerListenPort << endl;

// Connect to the IP and Port
if( ClientSObject.Connect( szServerIP, iServerListenPort ) )
{
while (true)
{
while ( !_kbhit() )
{
iBytesSent = ClientSObject.Send(&quot;Testing&quot;,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 << &quot;<Server> Client Connected to Port &quot; << 6000 << &quot;; ID: &quot; << clients << endl;
ReleaseMutex( g_hCreditMutex );
}
}
 
>> Well then how do you do it?

I don't normally post a whole bunch of code telling you EXACTLY what to do, this is just pseudocode, you will have to modify it to suit your app's needs.

Code:
int main(int argc,char* argv[])
{
   SOCKET sListen = socket(...blah...);
   bind(sListen,...blah...);
   listen(sListen,...blah...);

   while (!_condition_that_makes_you_exit) {
      SOCKET sConn = accept(sListen,...blah...);
      CreateThread(blah,blah,ConnectionProc,(LPVOID)sConn,blah,blah);
   }

   return 0;
}

DWORD WINAPI ConnectionProc(LPVOID lpParameter)
{
   SOCKET s = (SOCKET)lpParameter;
   // now you can make calls on the socket. No synchronization required
}

I really hope that helps.
 
how do I create two or more thread and sync them properly...
give me some pseudo code of it.
and anyone know the usage on _beginthread (C run-time).
pseudo codes might be useful.
Thanks.
 
>> how do I create two or more thread and sync them properly...

How you synchronize them depends on your requirements.

>> anyone know the usage on _beginthread (C run-time).

The documentation is completely clear on the usage of _beginthread(). Your question needs to be defined more clearly. What part of the documentation do you have problems with?

Also starting a new question at the end of 3 month old thread is not exactly the correct usage of the forum. Start a new thread in the forum with a short informative subject and the content of your question.


-pete
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top