The UNIX and Linux Forums  

Go Back   The UNIX and Linux Forums > Top Forums > High Level Programming
Google UNIX.COM


High Level Programming Post questions about C, C++, Java, SQL, and other programming languages here.

More UNIX and Linux Forum Topics You Might Find Helpful
Thread Thread Starter Forum Replies Last Post
Qmail is working. Can't log into Pop3 server stufine UNIX for Dummies Questions & Answers 0 12-29-2006 06:30 PM
SUSE 9 and 10 NIS clients with RedHat 8.0 NIS server not working fishsponge UNIX for Advanced & Expert Users 1 12-13-2005 07:13 AM
chmod (permissions) * not working on remote server sdlayeeq UNIX for Advanced & Expert Users 3 05-06-2005 11:02 AM
multi-threaded server, pthreads, sleep Parahat Melayev High Level Programming 0 03-16-2005 09:38 AM
jsp not working on linux running tomcat server mile1982 Linux 1 10-14-2004 03:18 AM

Reply
 
Submit Tools LinkBack Thread Tools Search this Thread Display Modes
  #1  
Old 06-12-2008
Registered User
 

Join Date: Jun 2008
Posts: 3
tcp server using pthreads is not working...ne help plz?

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:

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...
Reply With Quote
Forum Sponsor
  #2  
Old 06-15-2008
Registered User
 

Join Date: Jun 2008
Posts: 3
No passers-by???
Reply With Quote
  #3  
Old 10-23-2008
Registered User
 

Join Date: Oct 2008
Posts: 2
i think for each thread you have to make different pthread_t child like array to store that child threads in to it...
Reply With Quote
  #4  
Old 10-24-2008
Moderator
 

Join Date: Dec 2003
Location: /dev/fl
Posts: 1,059
I have modified your code so that it works. In addition I removed the pthread_create() call by replacing it with a PTHREAD_CREATE_DETACHED attribute in pthread_create.
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();}

/* servlet thread - get & convert the data */
void *servlet(void *arg)
{
   int client = (int)arg;
   int n;
   char s[100];

   /* process 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);
   pthread_exit(0);          /* terminate the thread */
}

int main(int argv, char *args[])
{
   struct sockaddr_in addr;
   int sd, port;
   int csd;
   pthread_t child;
   int on = 1;
   pthread_attr_t pattr;

   if ( argv != 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");

   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;
   if (bind(sd,(struct sockaddr*)&addr, sizeof(addr)) != 0)
      panic("bind");

   /* set size of request queue to 10 */
   if (listen(sd, 10) < 0)
      panic("listen");

   /* set thread create attributes */
   pthread_attr_init(&pattr);
   pthread_attr_setdetachstate(&pattr, PTHREAD_CREATE_DETACHED);

   while (1) {
      cout << "Waiting for a new connection ...." << endl;
      csd = accept(sd, NULL, NULL);
      if (csd < 0)
         panic("accept");
      cout << "New connection accepted on socket: " << csd << endl;
      pthread_create(&child, &pattr, servlet, (void *)csd);
   }

   close(sd);
   exit(0);
}
Reply With Quote
  #5  
Old 10-24-2008
Registered User
 

Join Date: Oct 2008
Posts: 2
Thank you, for uplowding the fixed code i did have another problem and i did findout what was going wrong with my code, tnx for your code...
Reply With Quote
Google The UNIX and Linux Forums
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes




All times are GMT -7. The time now is 06:11 PM.


Powered by: vBulletin, Copyright ©2000 - 2006, Jelsoft Enterprises Limited.
The UNIX and Linux Forums Content Copyright ©1993-2008. All Rights Reserved.Ad Management by RedTyger Visit The Complex Event Processing Blog

Content Relevant URLs by vBSEO 3.2.0