Hi,
I am new to using threads in C++ though I have been wkring on C++ for past 1.5 years...I want to write a TCP server that serves multiple client connections...to start off..i have been working on a simple tcp echo server trying to understand how threads work....
this is my server code:
#include <sys/socket.h>
#include <sys/types.h>
#include <iostream>
#include <string>
#include <resolv.h>
#include <pthread.h>
#include <fcntl.h>
#include <netdb.h>
using namespace std;
void panic(char *msg);
#define panic(m) {perror(m); abort();}
/*****************************************************************************
*** This function makes the socket non-blocking!
*****************************************************************************/
void nonblock(int &sockfd)
{
int opts;
opts = fcntl(sockfd, F_GETFL);
cout<<"in opt"<<endl;
if(opts < 0)
panic("fcntl(F_GETFL)\n")
opts = (opts | O_NONBLOCK);
if(fcntl(sockfd, F_SETFL, opts) < 0)
panic("fcntl(F_SETFL)\n")
cout<<"after opt"<<endl;
}
/*****************************************************************************/
/*** This program creates a simple echo server: whatever you send it, it ***/
/*** echoes the message back. ***/
/*****************************************************************************/
void *servlet(void *arg) /* servlet thread */
{ /* get & convert the data */
int *client = (int*)arg;
int n;
char s[100];
pthread_detach(pthread_self());
/* proc client's requests */
memset(s, '\0', 100);
while( (n = (read(*client,s,100)) ) > 0 )
{
if (s[0] == 'Q')
break;
printf("msg: %s", s);
write(*client,s,n);
memset(s, '\0', n);
}
close(*client);
return 0; /* terminate the thread */
}
int main(int count, char *args[])
{ struct sockaddr_in addr;
int sd, port;
if ( count != 2 )
{
printf("usage: %s <protocol or portnum>\n", args[0]);
exit(0);
}
/*---Get server's IP and standard service connection--*/
if ( !isdigit(args[1][0]) )
{
struct servent *srv = getservbyname(args[1], "tcp");
if ( srv == NULL )
panic(args[1]);
printf("%s: port=%d\n", srv->s_name, ntohs(srv->s_port));
port = srv->s_port;
}
else
port = htons(atoi(args[1]));
/*--- create socket ---*/
sd = socket(PF_INET, SOCK_STREAM, 0);
if ( sd < 0 )
panic("socket");
int on = 1;
if ( (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) ) < 0 )
panic("setsockoptions");
/*--- bind port/address to socket ---*/
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = port;
addr.sin_addr.s_addr = INADDR_ANY; /* any interface */
if ( bind(sd, (struct sockaddr*)&addr, sizeof(addr)) != 0 )
panic("bind");
/*--- make into listener with 10 slots ---*/
if ( listen(sd, 10) != 0 )
panic("listen")
/*--- begin waiting for connections ---*/
else
{ int csd;
pthread_t child;
FILE *fp;
cout<<"Here: "<<endl;
while (1) /* process all incoming clients */
{
csd = accept(sd, NULL, NULL); /* accept connection */
if (csd > 0 )
{
cout<<"New connection accepted on socket : "<<csd<<endl;
// nonblock(csd);
pthread_create(&child, 0, &servlet, &csd); /* start thread */
}
}
}
close(sd);
pthread_exit(NULL);
}
But the server is behaving in a strange manner..It is able to handle just one client at a time. When i connect multiple clients to it, only the last connection gets the echo..as for the rest...the connections are neither closed nor the messages are echoed...the client just stalls!
One more observation....the last message given by previous client is echoed to the latest connection (i.e to the latest client)...and then no more echoes to the previous client..
Am i missing something here? ne help is highly appreciated...