Hi everybody. As of now, my server will accept clients in a loop, and will pass those clients off into a new windows thread. Inside the thread, the server will be able to receive any data each client may send.

When a client connects, the clientsConnected variable increments. So when 3 clients have connected, clientsConnected will hold a value of 3.

Trouble is, I do not know how to better maintain these connections.

Things I want to implement, but don't know how.

  • If a client disconnects, I want clientsConnected to drop down to 2.
  • I want to be able to hold data relating to each socket, such as "name".
  • I want to be able to loop through this container of all sockets and be able to send a message to all of them (client0, client1, client2, etc.) depending on how you help me manage all of these sockets.

Here is my current code:

#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <winsock.h>
#include <iostream>
using namespace std;


// thread for receiving commands
DWORD WINAPI receive_commands(LPVOID lpParam)
{

	//set socket to the socket passed in as parameter
	SOCKET current_client = (SOCKET)lpParam;

	char receiveBuffer[256];	//buffer to hold received data
	char sendBuffer[256];	//buffer to hold sent data
	int result;		//contains return values for error checking

	//main loop
	while (true)
	{
		result = recv(current_client, receiveBuffer, sizeof(receiveBuffer), 0);
		Sleep(10);

		if (result > 0) 
		{
			cout << "Client " << "??: " << receiveBuffer << endl;
			if(strstr(receiveBuffer, "hello"))
			{
				//greet the user
				strcpy(sendBuffer, "Hello.");
				Sleep(10);
				send(current_client, sendBuffer, sizeof(sendBuffer), 0);
			}
			
			if(strstr(receiveBuffer, "goodbye"))
			{
				//disconnect the user

				strcpy(sendBuffer, "Goodbye!");
				Sleep(10);
				send(current_client, sendBuffer, sizeof(sendBuffer), 0);

				//close the socket and end the thread
				closesocket(current_client);
				
				ExitThread(0);
			}

			//clear the buffers
			strcpy(sendBuffer, "");
			strcpy(receiveBuffer, "");
		}
	} // end while
} // end receive_commands

int main()
{

	SOCKET sock; //the master socket which listens for connections
	DWORD thread; //for the thread
	WSADATA wsaData;
	sockaddr_in server;
	int port = 54321;
	int clientsConnected = 0;

	cout << "Server v1.0\n";
	cout << "===================\n";

	//start winsock
	int ret = WSAStartup(MAKEWORD(2,2), &wsaData);
	if(ret != 0) 
	{ 
		cout << "Winsock failed to start.\n";
		system("pause");
		return 1; 
	} //error checking
	else 
	{
		cout << "\nVersion: " << wsaData.wVersion
			 << "\nDescription: " << wsaData.szDescription
			 << "\nStatus: " << wsaData.szSystemStatus << endl << endl;
	}

	//fill in winsock struct
	server.sin_family = AF_INET;
	server.sin_addr.s_addr = INADDR_ANY;
	server.sin_port = htons(port);  //listen on port 54321

	//create the socket
	sock = socket(AF_INET, SOCK_STREAM, 0);
	if(sock == INVALID_SOCKET) 
	{ 
		cout << "Invalid Socket.\n";
		system("pause");
		return 1; 
	} //error checking

	//bind the socket to our port (built in error-checking)
	if( bind(sock, (sockaddr*)&server, sizeof(server)) != 0 ) 
	{ 
		printf("");
		return 1; 
	} 

	//listen for a connection
	if(listen(sock, 5) != 0) { return 1; }

	//client socket
	SOCKET client;
	sockaddr_in from;
	int fromlen = sizeof(from);

	//loop forever
	while (true)
	{
		//accept connections 
		client = accept(sock, (struct sockaddr*)&from, &fromlen);
		cout << "Client connected.\n";
		clientsConnected++;
		cout << "Clients online: " << clientsConnected << endl;

		//create a thread and pass new client socket as parameter
		CreateThread(NULL, 0, receive_commands, (LPVOID)client, 0, &thread);
		
	}

	//shutdown winsock
	closesocket(sock);
	WSACleanup();

	//exit
	return 0;
}

Recommended Answers

All 2 Replies

I like using IOCP I/O completion Ports. Works very nicely for minimal threads to maintain thousands of sockets!

Works well for only a couple sockets as well! Its a worker thread to event manager.

It involves, events, sockets, worker threads, and a IOCP setup. You can even assign a user value to each socket this way so when a thread wakes up from a socket event, you can associate it with an exact connection in your code. Something not easily done the old fashioned way!

bt if the client1 want to send the msg to client2......through server is it possible..??

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.