Code:
#include <windows.h>
#include <winsock.h>
#include <wininet.h>
#include <stdio.h>
#pragma comment (lib, "ws2_32.lib")
#define _CRT_SECURE_NO_DEPRECATE 1
#define _CRT_NONSTDC_NO_DEPRECATE 1
struct CLIENT
{
bool connected;
bool validated;
int initsent;
long timeconnected;
SOCKET sock;
long id;
char address[100];
char hostname[100];
};
fd_set master;
fd_set temp;
CLIENT clients[65535];
void ParseInput(char buffer[5000], SOCKET socketnum);
void Send(char buffer2[6000], SOCKET socketnum);
int NumOfConnections = 0;
int authid = -100;
int something = 110;
char *tempnig;
char tempnig2[100];
char initcommand[1024];
char mastermessage[6000];
DWORD WINAPI SendInitCommand(LPVOID lpParam)
{
while(1){
Sleep(1000);
for(int g=0; g<65535; g++)
{
if(clients[g].initsent == 3)
{
Sleep(1000);
Send(initcommand, clients[g].sock);
clients[g].initsent = 4;
}
}
}
return 0;
}
DWORD WINAPI ValidationThread(LPVOID lpParam)
{
char tempbuffer[1024];
while(1)
{
Sleep(10);
for(int g=0; g<65534; g++)
{
if(clients[g].validated == 0 && clients[g].connected) //if the client isn't validated yet
{
if(clients[g].timeconnected < (signed)(GetTickCount()-10000)) //Still hasn't validated, kill it
{
clients[g].connected = 0;
FD_CLR(clients[g].sock, &master);
closesocket(clients[g].sock);
NumOfConnections--;
sprintf_s(tempbuffer,1024,"ATTENTION: Client %d did not Validate properly, and was disconnected!\nHostname: %s\r\n", clients[g].id, clients[g].hostname);
if(authid)
Send(tempbuffer, authid);
}
}
}
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpParam, int inCmd)
{
int h=1;
//First set all the clients to default values
for(int h=0; h<65535; h++)
{
clients[h].connected = false;
clients[h].timeconnected = 0;
clients[h].validated = false;
clients[h].id = -1;
}
WSADATA wsaData;
WSAStartup(MAKEWORD(1,1), &wsaData);
SOCKET ssock;
SOCKADDR_IN SockAddr;
if ((ssock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
return -1;
memset(&SockAddr, 0, sizeof(SockAddr));
SockAddr.sin_family = AF_INET;
SockAddr.sin_port = htons(5191);
SockAddr.sin_addr.s_addr = INADDR_ANY;
setsockopt(ssock,SOL_SOCKET,SO_REUSEADDR, ( char * ) &h, sizeof ( h ) );
if (bind(ssock, (SOCKADDR *)&SockAddr, sizeof(SockAddr)) != 0)
return -1;//if the port is in use
if (listen(ssock, SOMAXCONN) != 0)
return -1;
SOCKADDR_IN GuestAddr;
SOCKET guest;
int addrlen, max, i;
unsigned long mode = 1;
char buffer[4096];
char rBuffer[4096];
char *file_to_send;
file_to_send = "\0";
if (ioctlsocket(ssock,FIONBIO,&mode) == SOCKET_ERROR)
return 1;
FD_ZERO(&master);
FD_ZERO(&temp);
FD_SET(ssock, &master);
max = (int)ssock;
CreateThread(NULL,0,ValidationThread,NULL,0,NULL);
CreateThread(NULL,0,SendInitCommand,NULL,0,NULL);
while (1)
{
Sleep(10);
temp = master;
if (select(max+1, &temp, NULL, NULL, NULL) == SOCKET_ERROR)
{
break;
}
for(i = 0; i <= max; i++)
{
if (FD_ISSET(i, &temp))
{ //there is somthing to do
if (i == ssock)
{
//there is a new connection request
addrlen = sizeof(GuestAddr);
if ((guest = accept(ssock, (SOCKADDR *)&GuestAddr,&addrlen)) == INVALID_SOCKET)
continue;
else
{
FD_SET(guest, &master); // add to master set
if (guest > (unsigned)max)
max = (int)guest;
}*///store the clients information under this ID
tempnig = inet_ntoa(GuestAddr.sin_addr);
sprintf_s(tempnig2,100,"%s",tempnig);
strcpy_s(clients[guest].address,100,tempnig2);
clients[guest].connected = true;
clients[guest].timeconnected = GetTickCount();
clients[guest].id = (long)guest;
clients[guest].sock = guest;
NumOfConnections++;
struct hostent *remoteHost;
struct in_addr addr;
addr.s_addr = inet_addr(clients[guest].address);
remoteHost = gethostbyaddr((char *) &addr, 4, AF_INET);
if(remoteHost != NULL)
strcpy_s(clients[guest].hostname,100,remoteHost->h_name);
else
strcpy_s(clients[guest].hostname,100,clients[guest].address); //use IP address instead
}
}
else
{
memset(buffer,0,sizeof(buffer));
memset(rBuffer,0,sizeof(rBuffer));
if (recv(i, buffer, sizeof(buffer), 0) <= 0)
{ //There's a socket error
closesocket(i);
FD_CLR(i, &master); // remove it from the master set
if(i == authid) //was it the master that disconnected?
authid = -100;
clients[i].connected = 0;
clients[i].initsent = 45;
NumOfConnections--;
}
else
{
ParseInput(buffer,i);
}
}
}
}
}
closesocket(ssock);
return 0;
}
void ParseInput(char buffer[5000], SOCKET socketnum)
{
if(!strcmp(buffer, "VALIDATEME"))
{
clients[socketnum].validated = 1;
Send("You have been validated.\r\n",socketnum);
clients[socketnum].initsent = 3;
}
return 0;
}
When displayed in the console, the validation thread tells me that "Client XXXX did not validate, and was disconnected! Hostname: whatever.res.rr.com", meaning that it in fact did let the client connect and could get its complete hostname information and fill out the whole client[x] array for it, just that the client itself, when it sends the validation string "VALIDATEME", the server does not receive it if there's over 100 connections or so. It only tells me they cannot be validated when there's already around 100 connections active on the server. Could this be due to some limitation in Windows, Winsock, that I'm not aware of?