![]() |
| | #1 |
| Registered User Join Date: Jul 2002
Posts: 47
| Select handling more then 500 connections My errorhandler is telling me the system seg faults when it tries to use the FD_SET command once I get over 500 or so connections. This mainly happens when my program is accepting connections. Once someone is already connected it does not seem to have a problem in this area, but new connections can cause the segmentation fault. if anyone knows why this is doing this please let me know. Here is the code for my Socket_Core Code: void cSCore::runcore(void)
{
/*Lets Initialize Some Variables*/
int *lsfd = new int; //Listening File Descriptor
int *nsfd = new int; //Sfd For New Connections
int returnval;
int *maxfd = new int;
char *buffer; //Temporary Message Buffer
char *charbuffer = new char[1];
struct sockaddr_in *newc = new sockaddr_in;
fd_set *cset = new fd_set;
fd_set *master = new fd_set;
memset(charbuffer,0,1);
*lsfd = Socket->cs_serve(Port);
int *optval = new int;
*optval = 1;
setsockopt(*lsfd,SOL_SOCKET,SO_REUSEADDR,optval,sizeof(*optval));
//FD_ZERO(cset);
FD_ZERO(master);
FD_ZERO(cset);
FD_SET(*lsfd, master); //Add the listening sfd to the FD set
*maxfd = *lsfd;
sMainUsers *tempuser;
while(enabled)
{
*cset = *master;
select((*maxfd)+1,cset,NULL,NULL,NULL);
if(FD_ISSET(*lsfd, cset)) //If It is a New Connection
{
*nsfd = accept(*lsfd,NULL,(socklen_t *)sizeof(*newc));
ErrorHandler->ProduceError(0,"cSCore::runcore()","New Connection Received");
if(!UserHandler->AddUser(*nsfd,"unsupported"))
{
ErrorHandler->ProduceError(0,"cSCore::runcore()","Failed To Add User");
close(*nsfd);
}
else
{
info("cSCore::runcore()","Adding to FD Set");
FD_SET(*nsfd,master);
if(*nsfd > *maxfd)
*maxfd = *nsfd;
}
}
else
{
ErrorHandler->ProduceError(0,"cSCore::runcore()","Data Received");
tempuser = UserHandler->GetUser(0);
//ErrorHandler->ProduceError(0,"cSCore::runcore()","UserPtr Caught");
while(tempuser != NULL)
{
//ErrorHandler->ProduceError(0,"cSCore::runcore()","looping list");
/*A User wants to send something*/
if(FD_ISSET(tempuser->sfd,cset) && tempuser->sfd != *lsfd)
{
*nsfd = tempuser->sfd;
ErrorHandler->ProduceError(0,"cSCore::runcore()","reading data");
returnval = Socket->cs_read(*nsfd,charbuffer,1);
//printf("Buffer value: %d\n",int(charbuffer[0]));
//Check For Disconnects
if(returnval == 0)
{
ChannelHandler->UserDisconnected(*nsfd);
info("cSCore::runcore()","User Disconnected From Channels");
UserHandler->RemoveUser(*nsfd);
info("cSCore::runcore()","User Disconnected");
close(*nsfd);
FD_CLR(*nsfd,master);
if(UserHandler->numusers == 0)
{
FD_ZERO(master);
FD_SET(*lsfd,master);
}
break;
}
else
{
if(int(charbuffer[0]) == -1) //Byte 255
{
this->parsecmd(*nsfd,tempuser->UserBuffer->buffer);
(tempuser->UserBuffer->done) = true;
}
else if((tempuser->UserBuffer->strsize) < ((tempuser->UserBuffer->buffersize) - 1))
{
tempuser->UserBuffer->buffer[(tempuser->UserBuffer->strsize)] = charbuffer[0];
(tempuser->UserBuffer->strsize)++;
}
else if((tempuser->UserBuffer->buffersize) < 512)
{
(tempuser->UserBuffer->buffersize) += 5;
buffer = new char[(tempuser->UserBuffer->buffersize)];
memset(buffer,0,(tempuser->UserBuffer->buffersize));
char *temp = tempuser->UserBuffer->buffer;
strcpy(buffer,temp);
buffer[(tempuser->UserBuffer->strsize)] = charbuffer[0];
(tempuser->UserBuffer->strsize)++;
tempuser->UserBuffer->buffer = buffer;
delete [] temp;
}
else
{
(tempuser->UserBuffer->done) = true;
}
if((tempuser->UserBuffer->done) == true)
{
char *temp = tempuser->UserBuffer->buffer;
tempuser->UserBuffer->buffer = new char[10];
memset(tempuser->UserBuffer->buffer,0,10);
(tempuser->UserBuffer->strsize) = 0;
(tempuser->UserBuffer->buffersize) = 10;
(tempuser->UserBuffer->done) = false;
delete [] temp;
}
}
break;
}
tempuser=tempuser->next;
}
}
}
close(*lsfd);
delete master;
delete cset;
delete nsfd;
delete maxfd;
delete lsfd;
delete [] buffer;
}
|
| Chronom1 is offline | |
| | #2 |
| Registered User Join Date: Sep 2004 Location: California
Posts: 3,020
| You aren't even checking the return value of select. If select is giving you an error, you wouldn't even know it. |
| bithub is offline | |
| | #3 |
| and the hat of Jobseeking Join Date: Aug 2001 Location: The edge of the known universe
Posts: 21,683
| delete master; delete cset; delete nsfd; delete maxfd; delete lsfd; delete [] buffer; All these are small variables - dynamic allocation of them is pretty pointless. > char *charbuffer = new char[1]; This is especially pointless. You also don't delete it, but you do delete buffer, which is probably not what you wanted. Try splitting the code into several smaller functions. You have so much code, with so much indentation that it's hard to see what is going on. Using tabs for indentation is a bit of a problem on this board, since the default tabstop width is quite large, thus exagerating the amount of indentation. |
| Salem is offline | |
| | #4 |
| Registered User Join Date: Jul 2002
Posts: 47
| Alright, Thanks for the help, I just realized what you meant about me deleting buffer instead of charbuffer. I know that the allocation is minimal, but the program is so huge that I am trying to keep as much out of the stack as possible. I do know that it is crashing here though. I am going to try reading the return value of select and see what that gets me. Thanks, Is there a max connections on Select? and if so what is the limit? |
| Chronom1 is offline | |
| | #5 |
| and the hat of Jobseeking Join Date: Aug 2001 Location: The edge of the known universe
Posts: 21,683
| > Is there a max connections on Select? Yes Code: /* Maximum number of file descriptors in `fd_set'. */ #define FD_SETSIZE __FD_SETSIZE Yeah, but if you're trashing memory, this is almost certainly not the cause (only the effect) > I am trying to keep as much out of the stack as possible. Unless you're working with large arrays, I don't think its worth doing - certainly not if you're going to end up causing memory leaks with faulty memory allocation and deletion. > tempuser->UserBuffer->done If you create a couple of functions to hide all this detail, the code will be a lot clearer Like Code: AddCharToUserBuffer( tempuser, ch ); MarkUserBufferComplete( tempuser ); |
| Salem is offline | |
| | #6 |
| Registered User Join Date: Jul 2002
Posts: 47
| Alright, I did check the select and hers what I got after the last connection before it segfaults select returns a 1 but the loop does not find a new connection or any data to be read. Then it does the same thing a second time and after that seg faults.. also here is a bit of cleaned up code. Code:
/****************************************************************/
/* FileName: cSCore.cpp */
/* Author: David Estes(Chrono) */
/* CopyRight 2004,2005 David Estes */
/* Under the GPL License */
/* FOR NON-COMMERCIAL USE ONLY */
/****************************************************************/
//====================
//Revisement History |
//====================
//02/23/2005 -- Moved Several Functions into cSCore-2.cpp to make file smaller
//
//
//====================
#include"cSCore.h"
#include"getarg.h"
void cSCore::runcore(void)
{
/*Lets Initialize Some Variables*/
int lsfd; //Listening File Descriptor
int nsfd; //Sfd For New Connections
int returnval;
int maxfd = 0;
char *buffer; //Temporary Message Buffer
char *charbuffer = new char[1];
struct sockaddr_in newc;
fd_set *cset = new fd_set;
fd_set *master = new fd_set;
memset(charbuffer,0,1);
lsfd = Socket->cs_serve(Port);
int optval = 1;
setsockopt(lsfd,SOL_SOCKET,SO_REUSEADDR,&optval,sizeof(optval));
setsockopt(lsfd,SOL_SOCKET,SO_LINGER,&optval,sizeof(optval));
//FD_ZERO(cset);
FD_ZERO(master);
FD_ZERO(cset);
FD_SET(lsfd, master); //Add the listening sfd to the FD set
maxfd = lsfd;
sMainUsers *tempuser;
int SelReturnVal=0;
printf("Max FD_SIZE = %d\n",FD_SETSIZE);
while(enabled)
{
*cset = *master;
SelReturnVal = select((maxfd)+1,cset,NULL,NULL,NULL);
printf("Select Returned %d\n",SelReturnVal);
if(FD_ISSET(lsfd, cset)) //If It is a New Connection
{
nsfd = accept(lsfd,NULL,(socklen_t *)sizeof(newc));
ErrorHandler->ProduceError(0,"cSCore::runcore()","New Connection Received");
if(!UserHandler->AddUser(nsfd,"unsupported"))
{
ErrorHandler->ProduceError(0,"cSCore::runcore()","Failed To Add User");
close(nsfd);
}
else
{
info("cSCore::runcore()","Adding to FD Set");
FD_SET(nsfd,master);
if(nsfd > maxfd)
maxfd = nsfd;
}
}
else
{
ErrorHandler->ProduceError(0,"cSCore::runcore()","Data Received");
tempuser = UserHandler->GetUser(0);
//ErrorHandler->ProduceError(0,"cSCore::runcore()","UserPtr Caught");
while(tempuser != NULL)
{
//ErrorHandler->ProduceError(0,"cSCore::runcore()","looping list");
/*A User wants to send something*/
if(FD_ISSET(tempuser->sfd,cset) && tempuser->sfd != lsfd)
{
nsfd = tempuser->sfd;
ErrorHandler->ProduceError(0,"cSCore::runcore()","reading data");
returnval = Socket->cs_read(nsfd,charbuffer,1);
if(returnval == 0) //Check To See If The User Disconnected
{
//UserDisconnected -- Notify Channels
ChannelHandler->UserDisconnected(nsfd);
info("cSCore::runcore()","User Disconnected From Channels");
//Notify UserHandler Of Disconnect and Remove All Memory Allocation of User
UserHandler->RemoveUser(nsfd);
info("cSCore::runcore()","User Disconnected");
close(nsfd);
FD_CLR(nsfd,master);
printf("%s%sUsers Connected: %d%s\n",FOREBLACK,BACKGREEN,UserHandler->numusers,NORMAL);
if(UserHandler->numusers == 0)
{
FD_ZERO(master);
FD_SET(lsfd,master);
}
break;
}
else
{
sUserBuffers *UserBuffer = tempuser->UserBuffer;
if(int(charbuffer[0]) == -1) //Byte 255
{
this->parsecmd(nsfd,GetUserBufferData(UserBuffer));
MarkUserBufferComplete(UserBuffer);
}
else
{
if(AddCharToUserBuffer(UserBuffer,charbuffer[0]) == -1)
MarkUserBufferComplete(UserBuffer);
}
if(IsBufferComplete(UserBuffer))
ResetUserBuffer(UserBuffer);
}
break;
}
tempuser=tempuser->next;
}
}
}
close(lsfd);
delete master;
delete cset;
delete [] charbuffer;
}
|
| Chronom1 is offline | |
![]() |
| Thread Tools | |
| Display Modes | |
|
Similar Threads | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| temperature sensors | danko | C Programming | 22 | 07-10-2007 07:26 PM |
| brace-enclosed error | jdc18 | C++ Programming | 53 | 05-03-2007 05:49 PM |
| Directional Keys - Useing in Console | RoD | C++ Programming | 38 | 10-06-2002 04:42 PM |
| FAQ: Directional Keys - Useing in Console | RoD | FAQ Board | 38 | 10-06-2002 04:42 PM |