Main.cpp

#include <stdio.h>
#include "CServer.cpp"

class EventReceiver:
public CServer
{
		void OnClientReceive(CServer* SVR)
		{
			char* Packet = SVR->GetReceivedBuffer();
			int packetsize = SVR->GetReceivedSize();
 
			PCLIENT_HANDLE clientthatsent = SVR->GetLatestReadClient();

			printf("\n Packet Recieved - %s", Packet);

			CLIENT_LIST_LOOP(SVR)
				if(CUR_CLIENT_SOCKETID != clientthatsent->sSocketId)
				{
					SVR->SendPacketToClient(Packet,packetsize,CUR_CLIENT);
					Sleep(250);
				}
			CLIENT_LIST_END_LOOP(SVR);
		}

		void OnClientConnection(CServer* SVR)
		{
			PCLIENT_HANDLE ConnectedClient = SVR->GetLatestConnectedClient();
			printf("\n Client  ( %s ) has connected!",ConnectedClient->szIpAddress);
		}
};

int main()
{
	CServer* Server = new CServer();
	EventReceiver* MyEvents = new EventReceiver();

	Server = MyEvents;

	Server->SetPort(555);
	Server->SetMaxClientAmmount(1000);
	Server->StartServer();
		
	while(1)
	{
		Sleep(1);
	}

	return 0;
}

CServer.cpp

#include "CServer.h"

CServer::CServer()
{
	m_CurrentReceivingClient = 0x0;
	m_CurrentAcceptingClient = 0x0;
	m_ClientListHead = 0x0;
	m_TotalClientCount = 0;
	m_ClientCount = 0;
	m_BufferSize = 0;
	m_Port = 0;
	m_MaxClient = 0;
	m_ListeningSocket = 0;
	m_isServerStarted = false;
	m_BufferReceived = (char*)malloc(4096);

	memset(m_BufferReceived,0,4096);
	WSAStartup(MAKEWORD(2,2),&m_WSAData);
}

CServer::CServer(int nPort)
{
	m_CurrentReceivingClient = 0x0;
	m_CurrentAcceptingClient = 0x0;
	m_ClientListHead = 0x0;
	m_TotalClientCount = 0;
	m_ClientCount = 0;
	m_BufferSize = 0;
	m_Port = nPort;
	m_MaxClient = 0;
	m_ListeningSocket = 0;
	m_isServerStarted = false;
	m_BufferReceived = (char*)malloc(4096);


	memset(m_BufferReceived,0,4096);
	WSAStartup(MAKEWORD(2,2),&m_WSAData);
}

CServer::~CServer()
{
	m_isServerStarted = false;
	free(m_BufferReceived);
	WSACleanup();
}

void CServer::SetPort(int nPort)
{
	m_Port = nPort;
}

bool CServer::StartServer()
{
	m_ListeningSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); 

	m_ServerAddress.sin_family = AF_INET;
	m_ServerAddress.sin_addr.s_addr = INADDR_ANY; 
	m_ServerAddress.sin_port = htons(m_Port);

	if(bind(m_ListeningSocket, (LPSOCKADDR)&m_ServerAddress, sizeof(struct sockaddr)) == SOCKET_ERROR)
	{
		return false;
	}

	m_isServerStarted = true;

	CreateThread(NULL,0,(unsigned long (__stdcall *)(void *))StartAccepting,this,0,NULL);
	CreateThread(NULL,0,(unsigned long (__stdcall *)(void *))StartReading,this,0,NULL);
	return true;
}

void CServer::AddClient(SOCKET sSocketId,char* szIpAddress,PCLIENT_HANDLE pListHead)
{
	if (!pListHead)
	{
		m_ClientListHead = (CLIENT_HANDLE*)malloc(sizeof(CLIENT_HANDLE));
		memset(m_ClientListHead,0,sizeof(CLIENT_HANDLE));
		pListHead = m_ClientListHead;
	}

	struct CLIENT_HANDLE* MyClients = pListHead;
	while (MyClients->next != 0x0)
	{
		if(MyClients->sSocketId == sSocketId)
			return;

		MyClients = MyClients->next;
	}

	/* Set Up Client Information */
	MyClients->sSocketId = sSocketId;
	memset(MyClients->szIpAddress,0,32);
	strcpy(MyClients->szIpAddress,szIpAddress);
	MyClients->nClientNumber = m_TotalClientCount++;
	m_CurrentAcceptingClient = MyClients;
	/* End of Client Information Set Up */

	MyClients->next = (CLIENT_HANDLE*)malloc(sizeof(CLIENT_HANDLE));
	memset(MyClients->next,0x0,sizeof(CLIENT_HANDLE));
	MyClients->next->previous = MyClients;
}

void CServer::RemoveClient(SOCKET sSocketId,PCLIENT_HANDLE pListHead)
{
	struct CLIENT_HANDLE* MyClients = pListHead;
	while (MyClients->next != 0x0)
	{
		if (MyClients->sSocketId == sSocketId)
		{
			if (MyClients->previous)
			{
				if (MyClients->next)
				{
					MyClients->previous->next = MyClients->next;
					MyClients->next->previous = MyClients->previous;
				}
				else
					MyClients->previous->next = 0x0;
				
				free(MyClients);
				
			}
			else
			{

				if (MyClients->next)
				{
					m_ClientListHead = MyClients->next;
					m_ClientListHead->previous = 0x0;
					free(MyClients);
				}
				else
				{
					memset(MyClients,0x0,sizeof(CLIENT_HANDLE));
				}
			}
			break;
		}
		else
		{
			MyClients = MyClients->next;
		}
	}	
}

bool CServer::isServerStarted()
{
	return m_isServerStarted;
}

DWORD CServer::StartAccepting(void* pParam)
{
	((CServer*)pParam)->ClientAccepting();
	return 0;
}

DWORD CServer::StartReading(void* pParam)
{
	((CServer*)pParam)->ClientReading();
	return 0;
}

int CServer::GetMaxClients()
{
	return m_MaxClient;
}

int CServer::GetClientCount()
{
	return m_ClientCount;
}

void CServer::ClientAccepting()
{
	SOCKET sLatestClient = 0;
	int length = sizeof(m_ServerAddress);
	for(;;)
	{
		while ( listen( m_ListeningSocket, SOMAXCONN ) == SOCKET_ERROR );
		if(GetMaxClients() == 0)
		{
			goto accept;
		}
		else
		{
			if(GetClientCount() < GetMaxClients())
			{
				goto accept;
			}
			else
			{
				goto end;
			}
		}
accept:
			sLatestClient = accept(m_ListeningSocket,(LPSOCKADDR)&m_ServerAddress,&length);
			if(sLatestClient != SOCKET_ERROR )
			{
				AddClient(sLatestClient,inet_ntoa(m_ServerAddress.sin_addr),m_ClientListHead);
				m_ClientCount++;
				if(m_CurrentAcceptingClient)
				{
					OnClientConnection(this);
				}
				m_CurrentAcceptingClient = 0x0;
			}
end:
			sLatestClient = 0;
	}
}

void CServer::ClientReading()
{
	int timer = 0;
	static struct timeval timestruct;
	timestruct.tv_sec = 0;
	timestruct.tv_usec = 10;
	int recvsize = 0;

	while(1)
	{
		timer++;
		if(timer > 50)
		{
			Sleep(1);
			timer = 0;
		}
		PCLIENT_HANDLE MyClients = GetClientListHead();
		if(MyClients)
		{
			while(MyClients->next)
			{
				timer++;
				if(timer > 50)
				{
					Sleep(1);
					timer = 0;
				}
				if(MyClients->sSocketId)
				{
					fd_set read;
					FD_ZERO(&read);
					FD_SET(MyClients->sSocketId,&read);
					select(MyClients->sSocketId+1,&read,0x0,0x0,&timestruct);
					if(FD_ISSET(MyClients->sSocketId,&read))
					{
						memset(m_BufferReceived,0,4096);
						recvsize = recv(MyClients->sSocketId,m_BufferReceived,4096,0);
						if(recvsize > 0)
						{
							m_CurrentReceivingClient = MyClients; 
							m_BufferSize = recvsize;
							OnClientReceive(this);
						}
						else
						{
							Sleep(1);
							closesocket(MyClients->sSocketId);
							RemoveClient(MyClients->sSocketId,m_ClientListHead);
							MyClients = m_ClientListHead;
							m_ClientCount--;
						}
					}

					FD_ZERO(&read);
				}
				if(MyClients)
				{
					if(MyClients->next)
						MyClients = MyClients->next;
				}
				else
					break;
			}
		}
	}
}

PCLIENT_HANDLE CServer::GetLatestReadClient()
{
	return m_CurrentReceivingClient;
}

PCLIENT_HANDLE CServer::GetLatestConnectedClient()
{
	return m_CurrentAcceptingClient;
}

PCLIENT_HANDLE CServer::GetClientListHead()
{
	return m_ClientListHead;
}

char* CServer::GetReceivedBuffer()
{
	return m_BufferReceived;
}

int CServer::GetReceivedSize()
{
	return m_BufferSize;
}

int CServer::SetMaxClientAmmount(int nAmmount)
{
	m_MaxClient = nAmmount;
	return m_MaxClient;
}

int CServer::SendPacketToClient(char* pPacket, int nSize,PCLIENT_HANDLE pClientHandle)
{
	return send(pClientHandle->sSocketId,pPacket,nSize,0);
}

int CServer::SendPacketToAllClients(char *pPacket, int nSize)
{
	PCLIENT_HANDLE MyClients = GetClientListHead();

	while(MyClients->next)
	{
		if(MyClients->sSocketId)
		{
			send(MyClients->sSocketId,pPacket,nSize,0);
		}
		MyClients = MyClients->next;
	}

	return 1;
}

CServer.h

#ifdef WIN32
#include <windows.h>
#endif

#ifdef WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#endif

#pragma comment(lib,"ws2_32.lib")

typedef struct CLIENT_HANDLE
{
	CLIENT_HANDLE* previous;
	SOCKET sSocketId;
	int nClientNumber;
	char szIpAddress[32];
	CLIENT_HANDLE* next;
}CLIENT_HANDLE,*PCLIENT_HANDLE;

PCLIENT_HANDLE MyClients;

#define CLIENT_LIST_LOOP(a) MyClients = a->GetClientListHead(); \
	while(MyClients->next) {

#define CLIENT_LIST_END_LOOP(a) MyClients = MyClients->next; }

#define CUR_CLIENT MyClients
#define CUR_CLIENT_IP MyClients->szIpAddress
#define CUR_CLIENT_SOCKETID MyClients->sSocketId
#define CUR_CLIENT_ID MyClients->nClientNumber

class CServer
{
	// ---------------------
	// Private delcaration
private:
	PCLIENT_HANDLE m_ClientListHead;
	PCLIENT_HANDLE m_CurrentAcceptingClient;
	PCLIENT_HANDLE m_CurrentReceivingClient;
	int m_TotalClientCount;
	int m_MaxClient;
	int m_ClientCount;
	int m_BufferSize;
	char* m_BufferReceived;
	bool m_isServerStarted;

	void AddClient(SOCKET sSocketId,char* szIpAddress,PCLIENT_HANDLE pListHead);
	void RemoveClient(SOCKET sSocketId,PCLIENT_HANDLE pListHead);

	void ClientAccepting();
	static DWORD StartAccepting(void* pParam);

	void ClientReading();
	static DWORD StartReading(void* pParam);
	// ---------------------
	// Protected declaration
protected:
	SOCKADDR_IN m_ServerAddress;
	SOCKET m_ListeningSocket;
	WSADATA m_WSAData;
	int m_Port;
	// ---------------------
	// Public delcaration
public:
	CServer();
	CServer(int nPort);
	~CServer();

	void SetPort(int nPort);

	virtual void OnClientReceive(CServer*){};
	virtual void OnClientConnection(CServer*){};

	PCLIENT_HANDLE GetLatestReadClient();
	PCLIENT_HANDLE GetLatestConnectedClient();
	PCLIENT_HANDLE GetClientListHead();
	
	int SendPacketToClient(char* pPacket,int nSize,PCLIENT_HANDLE pClientHandle);
	int SendPacketToAllClients(char* pPacket,int nSize);

	bool StartServer();
	bool isServerStarted();

	char* GetReceivedBuffer();
	int GetReceivedSize();

	int SetMaxClientAmmount(int nAmmount);
	int GetClientCount();
	int GetPort();
	int GetMaxClients();

};

ERRORS:

--------------------Configuration: Chat Server - Win32 Release--------------------
Compiling...
CServer.cpp
Main.cpp
Generating Code...
Linking...
Main.obj : error LNK2005: "public: __thiscall CServer::CServer(void)" (??0CServer@@QAE@XZ) already defined in CServer.obj
Main.obj : error LNK2005: "public: __thiscall CServer::CServer(int)" (??0CServer@@QAE@H@Z) already defined in CServer.obj
Main.obj : error LNK2005: "public: __thiscall CServer::~CServer(void)" (??1CServer@@QAE@XZ) already defined in CServer.obj
Main.obj : error LNK2005: "public: void __thiscall CServer::SetPortA(int)" (?SetPortA@CServer@@QAEXH@Z) already defined in CServer.obj
Main.obj : error LNK2005: "public: bool __thiscall CServer::StartServer(void)" (?StartServer@CServer@@QAE_NXZ) already defined in CServer.obj
Main.obj : error LNK2005: "private: void __thiscall CServer::AddClient(unsigned int,char *,struct CLIENT_HANDLE *)" (?AddClient@CServer@@AAEXIPADPAUCLIENT_HANDLE@@@Z) already defined in CServer.obj
Main.obj : error LNK2005: "private: void __thiscall CServer::RemoveClient(unsigned int,struct CLIENT_HANDLE *)" (?RemoveClient@CServer@@AAEXIPAUCLIENT_HANDLE@@@Z) already defined in CServer.obj
Main.obj : error LNK2005: "public: bool __thiscall CServer::isServerStarted(void)" (?isServerStarted@CServer@@QAE_NXZ) already defined in CServer.obj
Main.obj : error LNK2005: "private: static unsigned long __cdecl CServer::StartAccepting(void *)" (?StartAccepting@CServer@@CAKPAX@Z) already defined in CServer.obj
Main.obj : error LNK2005: "private: static unsigned long __cdecl CServer::StartReading(void *)" (?StartReading@CServer@@CAKPAX@Z) already defined in CServer.obj
Main.obj : error LNK2005: "public: int __thiscall CServer::GetMaxClients(void)" (?GetMaxClients@CServer@@QAEHXZ) already defined in CServer.obj
Main.obj : error LNK2005: "public: int __thiscall CServer::GetClientCount(void)" (?GetClientCount@CServer@@QAEHXZ) already defined in CServer.obj
Main.obj : error LNK2005: "private: void __thiscall CServer::ClientAccepting(void)" (?ClientAccepting@CServer@@AAEXXZ) already defined in CServer.obj
Main.obj : error LNK2005: "private: void __thiscall CServer::ClientReading(void)" (?ClientReading@CServer@@AAEXXZ) already defined in CServer.obj
Main.obj : error LNK2005: "public: struct CLIENT_HANDLE * __thiscall CServer::GetLatestReadClient(void)" (?GetLatestReadClient@CServer@@QAEPAUCLIENT_HANDLE@@XZ) already defined in CServer.obj
Main.obj : error LNK2005: "public: struct CLIENT_HANDLE * __thiscall CServer::GetLatestConnectedClient(void)" (?GetLatestConnectedClient@CServer@@QAEPAUCLIENT_HANDLE@@XZ) already defined in CServer.obj
Main.obj : error LNK2005: "public: struct CLIENT_HANDLE * __thiscall CServer::GetClientListHead(void)" (?GetClientListHead@CServer@@QAEPAUCLIENT_HANDLE@@XZ) already defined in CServer.obj
Main.obj : error LNK2005: "public: char * __thiscall CServer::GetReceivedBuffer(void)" (?GetReceivedBuffer@CServer@@QAEPADXZ) already defined in CServer.obj
Main.obj : error LNK2005: "public: int __thiscall CServer::GetReceivedSize(void)" (?GetReceivedSize@CServer@@QAEHXZ) already defined in CServer.obj
Main.obj : error LNK2005: "public: int __thiscall CServer::SetMaxClientAmmount(int)" (?SetMaxClientAmmount@CServer@@QAEHH@Z) already defined in CServer.obj
Main.obj : error LNK2005: "public: int __thiscall CServer::SendPacketToClient(char *,int,struct CLIENT_HANDLE *)" (?SendPacketToClient@CServer@@QAEHPADHPAUCLIENT_HANDLE@@@Z) already defined in CServer.obj
Main.obj : error LNK2005: "public: int __thiscall CServer::SendPacketToAllClients(char *,int)" (?SendPacketToAllClients@CServer@@QAEHPADH@Z) already defined in CServer.obj
Main.obj : error LNK2005: "struct CLIENT_HANDLE * MyClients" (?MyClients@@3PAUCLIENT_HANDLE@@A) already defined in CServer.obj
Release/Chat Server.exe : fatal error LNK1169: one or more multiply defined symbols found
Error executing link.exe.

Chat Server.exe - 24 error(s), 0 warning(s)

Don't #include "CServer.cpp" in main.cpp.
Instead #include "CServer.h" and move the CServer:: stuff from main.cpp to CServer.cpp.

i dont understand you sorry?

edit:

i did that now i have

--------------------Configuration: Chat Server - Win32 Release--------------------
Compiling...
CServer.cpp
Main.cpp
Generating Code...
Linking...
Main.obj : error LNK2005: "struct CLIENT_HANDLE * Clients" (?Clients@@3PAUCLIENT_HANDLE@@A) already defined in CServer.obj
Release/Chat Server.exe : fatal error LNK1169: one or more multiply defined symbols found
Error executing link.exe.

Chat Server.exe - 2 error(s), 0 warning(s)

i dont understand you sorry?

edit:

i did that now i have

Linking...
Main.obj : error LNK2005: "struct CLIENT_HANDLE * Clients" (?Clients@@3PAUCLIENT_HANDLE@@A) already defined in CServer.obj
Release/Chat Server.exe : fatal error LNK1169: one or more multiply defined symbols found
Error executing link.exe.

You probably have two times the following: PCLIENT_HANDLE Clients; One in main and the other in CServer, you need to remove or rename one.

The way you've structured your headers (.h) and implementation (.cpp) files is not very good and is probably causing the problem.

Typically for a class you should always have a header file which you have header file "guards" and inside you declare the class. It should look something like this:

#ifndef _CLASSFILENAME_H_      //part of header guard
#define _CLASSFILENAME_H_     // part of header guard

// necessary includes and stuff go here

class MyClass {
   public:
      MyClass();
      void Foo();
};

#endif   // end of header guard

Then your .cpp file which contains the actual class definition should look like this:

#include "Classfilename.h"

MyClass::MyClass() {
   // do constructor stuff here
}

void MyClass::Foo() {
   // do foo stuff here
}

Then you should have a main which is completely separate from the class in main.cpp. You simply include the class file header and now you can use the class.

#include "Classfilename.h"

int main() {
   MyClass x;
   x.Foo();

   return 0;
}
This article has been dead for over six months. Start a new discussion instead.