I worte a Client\Server chat room program a few weeks ago and it worked just fine (to a degree) so in an effort to finely polish it and make it perfect iv'e included the use of linked lists so i can delete disconnected users sockets and give a (theoretically) infinate amount of clients to connect to
However somewhere along the lines a bug has appeared that will only accept 3 clients then it seems to ignore the rest
But if I comment out the line marked below the program will let me accept as much users as I want but then make the program unuseable
so Im unsure on how to get around the problem.
Any leads on these probs would be awesome because iv'e gone over the code so many times and everything just seems to be in order to me.
Heres the Problematic code (The Listening socket and clients socets are all non blocking)
Code:
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iostream>
#define WELCOMEMSG "Welcome Console Chat V1.0 -- PRESS '^' TO EXIT!"
#define NONBLOCK 1
using namespace std;
struct Client //Define our Client Data structure
{
char Name[10];//this isn't being used yet...
int Socket;
struct sockaddr_storage client_addr;
socklen_t addr_size;
Client *Next;// for the linked list
};
int main()
{
WSADATA wsaData;
char port[5] = "8888";
cout << "Connect To Port: ";
cin >> port;
cout << "\n Connecting...\n";
struct addrinfo base, *server, *x; //Set up address struct and pointers
int status = 0; //Error checker
int sockdis = 0; //Socket Discriptor
Client *Root = new Client; //The Root Node
Client *Point; //The Scanning Node for pointing to a current node
Client *Temp; //Used As A Tempoary Place Holder
Client *Last; //Last Node before current node
Client *Disconect; //Nodes Marked to be Deleted
Point = Root;
Point->Next = 0;
int TempSock;
memset(&base, 0, sizeof base); //Clean out address struct
base.ai_family = AF_INET; //Set address struct's params
base.ai_socktype = SOCK_STREAM;
base.ai_flags = AI_PASSIVE;
/* INITIATE WSASTARTUP */
status = WSAStartup(MAKEWORD(2, 2), &wsaData);
cout << "Initalizing WSAStartup............ ";
if(status != 0){cout << "Error! \n";}
else{cout << "Success! \n";}
/* COLECT ADRESS INFORMATION */
status = getaddrinfo(NULL, port, &base, &server);
cout << "Collecting Address Information.... ";
if(status != 0){cout << "Error! \n";}
else{cout << "Success! \n";}
/* FIND AVALIABLE SOCKET */
for(x = server; x != NULL; x = x->ai_next)
{sockdis = socket(x->ai_family, x->ai_socktype, x->ai_protocol);}
cout << "Connecting To Socket.............. ";
if(sockdis == -1){cout << "Error! \n" ;}
else{cout << "Success! \n";}
/* BIND SOCKET TO PORT */
status = bind(sockdis, server->ai_addr , server->ai_addrlen);
cout << "Binding To Port................... ";
if(status != 0){status = WSAGetLastError(); cout << "Error: " << status << endl;}
else{cout << "Success! \n";}
/* WAIT FOR CLIENTS */
status = listen(sockdis, 15);
cout << "Listening On Port................. ";
if(status != 0)
{
status = WSAGetLastError(); cout << "Error: " << status << endl;
}
else
{
cout << "Success! \n\n";
cout << "Connected to socket: "<< sockdis << endl;
cout << "Connected to Port: "<< port << endl;
}
cout << "\nWaiting for client to connect...\n";
/* MAKE SOCKET NON BLOCKING MODE */
u_long mode = 1;
ioctlsocket(sockdis, FIONBIO, &mode);
char Data[1024];
int bytesrecvd;
int a = 0, b =0; //loop counters
/* MAKE NEW CLIENT SOCKET NON BLOCKING MODE */
ioctlsocket(Point->Socket, FIONBIO, &mode);
Point->Socket = -1;
/* LISTENING LOOP */
while(1)
{
Point->Socket = -1;
while(Point->Socket <= -1)
{
while(TempSock <= -1)
{
Point = Root;
while(Point->Next != 0)
{
Point = Point->Next;
}
Point->Socket = accept(sockdis, (struct sockaddr *)&Point->client_addr, &Point->addr_size);
Point = Root;
while(Point->Next != 0)
{
bytesrecvd = recv(Point->Socket , (char*)Data, sizeof Data, 0);// RECIVE DATA
if(bytesrecvd > 1) //IF MORE THEN ONE BYTE WAS SENT
{
status = WSAGetLastError();
cout << "ErrorNo; " << status << endl;
cout << Data << endl <<"Reviced Returned: " << bytesrecvd << endl;
Temp = Point;
Point = Root;
Last = Point;
while(1) //SEND RECIVED DATA TO ALL CLIENTS
{
bytesrecvd = send(Point->Socket , (char*)Data, bytesrecvd, 0);
cout << Data << endl <<"Send Returned: " << bytesrecvd << endl;
status = WSAGetLastError();
cout << "Error No: " << status <<endl;
if(bytesrecvd == -1)//if user has disconnected
{
cout << Point->Socket << " Has Disconnected!"<< endl;
Disconect = Point;
if(Point->Next == 0)// if at the last node
{
cout <<"Discon style Last Node"<<endl;
Last->Next = 0;
Point = Last;
}
else if(Point == Root)//if at the root node
{
cout <<"Discon style Root Node"<<endl;
Root = Root->Next;
Point = Root;
Last = Root;
}
else //if at a middle node
{
cout <<"Discon style Middle Node"<<endl;
Point = Point->Next;
Last->Next = Point;
}
cout <<"Deleteing Node..."<<endl;
delete(Disconect);
}
if(Point->Next == 0)
{
Point = Temp;
break;
}
Last = Point;
Point = Point->Next;
if(Point->Next == 0)
{
Point = Temp;
break;
}
}
}
Point = Point->Next;
}
}
}
//goto Last Client
Point = Root;
while(Point->Next != 0)
{Point = Point->Next;}
Point->Socket = TempSock;
cout << "Client Connected!" <<endl << "Client Port: " << Point->Socket << "\n\n";
send(Point->Socket , (char*)WELCOMEMSG, sizeof WELCOMEMSG, 0);//Send welcome message
Point->Next = new Client;
Point = Point->Next; // THIS LINE OF CODE DISALLOWS ME TO ADD MORE THEN 3 CLIENTS
Point->Socket = -1;
Point->Next = 0;
ioctlsocket(Point->Socket, FIONBIO, &mode);
}
// CLEAN UP LINKED LIST HERE
Point = Root;
while(Point->Next != 0)
{
Temp = Point;
Point = Point->Next;
delete(Temp);
}
WSACleanup();
freeaddrinfo(server);
system("pause");
}//END OF MAIN