Click to See Complete Forum and Search --> : Please help! accept function problems in Socket programming


natxie
February 5th, 2009, 09:55 AM
Hi,

I have a client-server socket program. It has been working fine for over a year, but recently it started to show strange behavior.
After the server program runs for a while, it will show in the top command saying it is using lots of CPU, MEM. I assume it means the server code is processing some requests. But I never sent a request from the client side(from a web page). When this happens, I try to send a request to the server, the server won't response. I looked at the output from the server side, it shows the accept was called before, though I didn't send any connect calls from the client. I guess the server stopped at the read().
Parts of the program is:

void CServer_pth::run_pth(Nabor_pth *Nab, Bool_pth *Bl, BnBayes_pth *Bnb, Focus_pth *Foc, Slice_Accpth *Sac) {

int i, nsid;

pNab = Nab;
pBl = Bl;
pBnb = Bnb;
pFoc = Foc;
pSac = Sac;

//create a stream socket
// Sock sp(AF_INET, SOCK_STREAM, 0);
if (!sp.good()) {
cout<<"sp.good() failed\n";
exit(1);
}

//Bind a name to the server socket
if (sp.bind(host, port) < 0) {
cout<<"sp.bind failed\n";
sp.~Sock();
exit(2);
}

for (i=0; i<NUM_THR; i++) {
if (pthread_create(&srvtid[i], &thread_attr, commsrv_pth,tdata[i])) {
perror("pthread_create");
cout<<"srvtid[i], i="<<i<<endl;
cout<<"error in pthread_create, in commsrv_pth\n";
exit(1);
}
}

sem_init(&smp,0, NUM_THR);

for (;;) { //this is a infinite loop, I don't see the option to turn the smile face off

sem_wait(&smp);
while ((nsid = sp.accept(0, 0)) < 0) {
cout<<"accept failed\n";
exit(1);
}


bot = bot%NUM_THR;
i = mat[bot];
cout<<"i in nsid ----> "<<i<<"\tnsid ---> "<<nsid<<endl;
*tdata[i] = nsid;
bot++;

pthread_mutex_lock(&mthread);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mthread);

}
}

extern "C" void *commsrv_pth(void *argp) {

cmd_Query cmd;
int i, t_nsid;

while (1) {

pthread_mutex_lock(&mthread);
pthread_cond_wait(&cond, &mthread);
pthread_mutex_unlock(&mthread);

pthread_mutex_lock(&mbotp);
botp = botp%NUM_THR;
i = mat[botp];
t_nsid = *tdata[i];
botp++;
pthread_mutex_unlock(&mbotp);

cout<<"i in nsid ----> "<<i<<"\tnsid ---> "<<t_nsid<<endl;
cout<<"wait to read MSG from a client socket\n";

// read MSG1 from a client socket
if (sp.read((char*)&cmd, sizeof(cmd_Query), 0,t_nsid) < 0) {
cout<<"failed in read\n";
return (int*)5;
}
cout<<"after waiting to read\n";

cmd = (cmd_Query)ntohl(cmd);
dispatch_pth(cmd, t_nsid);

close(t_nsid);

pthread_mutex_lock(&mtop);
top = top%NUM_THR;
mat[top] = i;
top++;
pthread_mutex_unlock(&mtop);


sem_post(&smp);
}
return NULL;

}

The above is creating 5(NUM_THR) threads first, then wait the call from clients. I also tried another way which is createing one thread at a time when there's a call from the client. But the same strange behaviour happeded.
void CServer_pth::run_pth(Nabor_pth *pNab, Bool_pth *pBl, BnBayes_pth *pBnb, Focus_pth *pFoc, Slice_Accpth *pSac) {

int i, nsid;

//create a stream socket
Sock sp(AF_INET, SOCK_STREAM, 0);
if (!sp.good()) {
cout<<"sp.good() failed\n";
//return 1;
}

//Bind a name to the server socket
if (sp.bind(host, port) < 0) {
cout<<"sp.bind failed\n";
//return 2;
}

for (i=0; i<NUM_THR; i++) {
tdata[i] = new Thrdata_pth(sp, pNab, pBl, pBnb, pFoc, pSac, i); }

sem_init(&smp,0, NUM_THR);

for (;;) { //this is a infinite loop, I don't see the option to turn the smile face off
while ((nsid = sp.accept(0, 0)) < 0) {
cout<<"accept failed\n";
//return 1;
}

sem_wait(&smp);

bot = bot%NUM_THR;
i = mat[bot];
cout<<"i in nsid ----> "<<i<<"\tnsid ---> "<<nsid<<endl;
tdata[i]->set_nsid(nsid);
if (pthread_create(&srvtid[i], &thread_attr, commsrv_pth,tdata[i])) {
perror("pthread_create");
cout<<"srvtid[i], i="<<i<<endl;
cout<<"error in pthread_create, in commsrv_pth\n";
exit(1);
}
bot++;
}
}

extern "C" void *commsrv_pth(void *argp) {

Thrdata_pth *data = (Thrdata_pth*)argp;
cmd_Query cmd;

cout<<"waiting for reading cmd_Query from a client\n";

// read MSG1 from a client socket
if ((data->t_sp).read((char*)&cmd, sizeof(cmd_Query), 0,data->t_nsid) < 0) {
cout<<"failed in read\n";
return (int*)5;
}

cmd = (cmd_Query)ntohl(cmd);
dispatch_pth(cmd, data);

close(data->t_nsid);

pthread_mutex_lock(&mtop);
top = top%NUM_THR;
mat[top] = data->iz;
top++;
pthread_mutex_unlock(&mtop);


sem_post(&smp);
return NULL;

}

Any advice? Thanks very much for help!!!

MikeAThon
February 5th, 2009, 05:03 PM
Difficult to read and understand your code, so it's hard to give an answer or a suggestion.

However, this code (from the first version of commsrv_pth) seems like it might be wrong:
if (sp.read((char*)&cmd, sizeof(cmd_Query), 0,t_nsid) < 0)
It seems wrong since (as I understand your code), the "sp" variable is your listening socket, not your connection socket. Your connection socket is the "nsid" variable, as returned from the call to sp.accept() (and as passed in to the thread).

The listening socket should simply listen() and accept() new connections. You should not try to read or write from/to it. Instead, when accept() indicates that a new connection has been accepted, read and wrote from/to the new socket provided as the return value from the accept() function.

Incidentally, please edit your post to insert [ code ][ /code ] tags (without the spaces) around your code. The [ code ][ /code ] tags format your code nicely, and eliminate those pesky smilies.

Mike