I turns out that it does use a array to store the clients, so I tried a snippet of code that ran through the entire array looking for clients to send to.
Code:
for (unsigned int i = 0; i < pollingSet.fd_count; i++)
{
clientsocket = pollingSet.fd_array[i];
if ((numbytes = send(clientsocket, buffer, messagesize, 0)) == SOCKET_ERROR)
{
cout<<"Failed to send message.\n";
}
}
If I run two clients and send some messages i get the following
Clients 1: (Send) Hi
Server: (Wait)
Clients 2: (Wait) (Send) Hello
Server: (Recv) Hi
Server: (Recv) Hello
Clients 1: (Recv) Hi
Clients 2: (Recv) Hello
Clients 1: (Send) Nice to meet you
Server: (Wait)
Clients 2: (Wait) (Send) You too
Server: (Recv) Nice to meet you
Server: (Recv) You too
Clients 1: (Recv) You too meet you
Clients 2: (Recv) Hiu too
The server is sending the messages to the clients but it seem that the clients combine the messages they send with the one they recieve. I am not sure why the server and client 2 wait.
Client:
Code:
#include <iostream>
#include <stdlib.h>
#include <winsock2.h>
#include <string.h>
using std::cout;
using std::cin;
int startup(unsigned short port, const char* serveraddress);
int main();
int cleanup(int socket);
int main()
{
char serverip[128];
cout<<"Input server IP:";
cin.getline(serverip, 127);
cout<<serverip;
int clientsocket;
clientsocket = startup(65050, serverip);
if (clientsocket == -1)
{
cout<<"Client failed to start.\nStopping program.\n";
cleanup (clientsocket);
return 0;
}
int numbytes;
#define MAX_MESSAGE_SIZE 4096
char buffer[MAX_MESSAGE_SIZE];
cout<<"Type messages bellow and press enter to send, To exit type 'quit'.\n";
for (;;)
{
gets(buffer);
if (strcmp(buffer, "quit") == 0)
{
break;
}
unsigned long messagesize = strlen(buffer);
messagesize = htonl(messagesize);
if ((numbytes = send(clientsocket, (char*)&messagesize, sizeof(messagesize), 0)) == SOCKET_ERROR)
{
cout<<"Failed to send message size.\n";
}
messagesize = htonl(messagesize);
if ((numbytes = send(clientsocket, buffer, messagesize, 0)) == SOCKET_ERROR)
{
cout<<"Send message failed.\n";
}
numbytes = recv(clientsocket, buffer, messagesize, 0);
if (numbytes == SOCKET_ERROR)
{
cout<<"Error! Failed to recieve message.\n";
continue;
}
cout<<"Message Received:"<<buffer<<"\n";
}
cleanup (clientsocket);
}
int startup(unsigned short port, const char* serveraddress)
{
int error;
WSAData wsaData;
if ((error = WSAStartup(MAKEWORD(2, 2), &wsaData)) == SOCKET_ERROR)
{
cout<<"Error! Winsock failed to start.\n";
return -1;
}
cout<<"Winsock started.\n";
int clientsocket = socket(AF_INET, SOCK_STREAM, 0);
if (clientsocket == SOCKET_ERROR)
{
cout<<"Error! Failed to create socket.\n";
return -1;
}
cout<<"Socket created.\n";
struct hostent *host_entry;
if ((host_entry = gethostbyname(serveraddress)) == NULL)
{
cout<<"Localising of host failed.\n";
return -1;
}
cout<<"Localization achevied.\n";
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons(port);
server.sin_addr.s_addr = *(unsigned long*) host_entry->h_addr;
if (connect(clientsocket, (sockaddr*)&server, sizeof(server)) == SOCKET_ERROR)
{
cout<<"Error! Failed to connect to server.\n";
return -1;
}
cout<<"Conenction acheived.\n";
cout<<"Client Started\n";
return clientsocket;
}
int cleanup(int socket)
{
closesocket(socket);
WSACleanup();
cout<<"Clean up complete.\n";
system("PAUSE");
}
Server:
Code:
#include <iostream>
#include <stdlib.h>
#include <winsock2.h>
using std::cout;
using std::cin;
int startup(unsigned short port);
int main();
int cleanup(int socket);
HANDLE threadHandle;
HANDLE mutexHandle;
FD_SET masterSet;
bool gQuitFlag = false;
int acceptthread(int* serverSocket)
{
int serversocket = *serverSocket;
for (;;)
{
unsigned int clientsocket = accept(serversocket, 0, 0);
cout<<"Waiting to accept connnections...\n";
if (clientsocket == SOCKET_ERROR)
{
cout<<"Error! Server failed to accept.\n";
gQuitFlag = true;
system("pause");
return 0;
}
else
{
WaitForSingleObject(mutexHandle, INFINITE);
FD_SET(clientsocket, &masterSet);
ReleaseMutex(mutexHandle);
cout<<"Client Connected\n";
}
}
}
int main()
{
int serversocket;
serversocket = startup(65050);
if (serversocket == -1)
{
cout<<"Server failed to start.\nStopping Program.\n";
system("pause");
return 0;
}
mutexHandle = CreateMutex(NULL, false, NULL);
if (mutexHandle == NULL)
{
cout<<"Failed to create mutex.\n";
cleanup(serversocket);
return 0;
}
int threadId;
threadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)acceptthread, &serversocket, 0, (LPDWORD)&threadId);
if (threadHandle == NULL)
{
cout<<"Acceptence tread failed to start.\n";
cleanup(serversocket);
return 0;
}
Sleep(100);
FD_ZERO(&masterSet);
for (;;)
{
if (gQuitFlag)
{
break;
}
WaitForSingleObject(mutexHandle, INFINITE);
FD_SET pollingSet = masterSet;
FD_SET pollingSet2 = masterSet;
ReleaseMutex(mutexHandle);
if (pollingSet.fd_count == 0)
{
continue;
}
timeval waitTime;
waitTime.tv_sec = 0;
waitTime.tv_usec = 0;
int result = select(pollingSet.fd_count, &pollingSet, &pollingSet, NULL, &waitTime);
if (result == 0)
{
continue;
}
if (result == SOCKET_ERROR)
{
cout<<"Failed to select.\n";
continue;
}
for (unsigned int i = 0; i < pollingSet.fd_count; i++)
{
unsigned int clientsocket = pollingSet.fd_array[i];
int numbytes;
#define MAX_MESSAGE_SIZE 4096
char buffer[MAX_MESSAGE_SIZE];
unsigned long messagesize;
numbytes = recv(clientsocket, (char*)&messagesize, sizeof(messagesize), 0);
if (numbytes == SOCKET_ERROR)
{
cout<<"Error! Failed to receive message size.\n";
int error = WSAGetLastError();
if (error == WSAECONNRESET)
{
WaitForSingleObject(mutexHandle, INFINITE);
FD_CLR(clientsocket, &masterSet);
ReleaseMutex(mutexHandle);
closesocket(clientsocket);
cout<<"Client Disconnected.\n";
continue;
}
else
{
cout<<"Recieve message failed.\n";
gQuitFlag = true;
system("pause");
break;
}
}
if (numbytes==0)
{
WaitForSingleObject(mutexHandle, INFINITE);
FD_CLR(clientsocket, &masterSet);
ReleaseMutex(mutexHandle);
closesocket(clientsocket);
cout<<"Client Disconnected.\n";
continue;
}
messagesize = ntohl(messagesize);
numbytes = recv(clientsocket, buffer, messagesize, 0);
if (numbytes == SOCKET_ERROR)
{
cout<<"Error! Recieve message failed.\n";
gQuitFlag = true;
system("pause");
break;
}
buffer[messagesize] = '\0';
cout<<"Message Received:"<<buffer<<"\n";
for (unsigned int i = 0; i < pollingSet.fd_count; i++)
{
clientsocket = pollingSet.fd_array[i];
if ((numbytes = send(clientsocket, buffer, messagesize, 0)) == SOCKET_ERROR)
{
cout<<"Failed to send message.\n";
}
}
}
}
}
int startup(unsigned short port)
{
int error;
WSAData wsaData;
if ((error = WSAStartup(MAKEWORD(2, 2), &wsaData)) == SOCKET_ERROR)
{
cout<<"Error! Winsock failed to start.\n";
return -1;
}
cout<<"Winsock started.\n";
int serversocket = socket(AF_INET, SOCK_STREAM, 0);
if (serversocket == SOCKET_ERROR)
{
cout<<"Error! Failed to create socket.\n";
return -1;
}
cout<<"Socket created.\n";
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons(port);
server.sin_addr.s_addr = INADDR_ANY;
if (bind(serversocket, (sockaddr*)&server, sizeof(server)) == SOCKET_ERROR)
{
cout<<"Error! Socket failed to bind.\n";
closesocket(serversocket);
return -1;
}
cout<<"Bind completed.\n";
if (listen(serversocket, 5) == SOCKET_ERROR)
{
cout<<"Error! Failed to listen on socket.\n";
closesocket(serversocket);
return -1;
}
cout<<"Listen Successful.\n";
cout<<"Server Started\n";
return serversocket;
}
int cleanup(int socket)
{
WaitForSingleObject(threadHandle, INFINITE);
CloseHandle(threadHandle);
CloseHandle(mutexHandle);
closesocket(socket);
WSACleanup();
cout<<"Clean up complete.\n";
system("PAUSE");
}
Note: This is my longest post ever XD