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