Thread: tcp server program .. does not get block on recv

  1. #1
    Registered User
    Join Date
    Mar 2008
    Location
    India
    Posts
    147

    tcp server program .. does not get block on recv

    Hello all,

    I am trying to run a listener on 5000 port , here my issue is once i get a connection it gets data through recv, and i send back a message based on a condition.

    But in next iterieation it does not get stop here in recv call.

    It contiously loop around for recv. my understanding is as the other side client is not sending any data to port 5000 , it should stop .

    Here i donot think iam opening a socket in non blocking mode.

    Can any body guide me where am i getting missed here.



    Code:
    #include <string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <unistd.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <sys/wait.h>
    #include <signal.h>
    #include <sys/wait.h>
    #include <syslog.h>
    
    #define MYPORT 5000
    
    #define BACKLOG 10
    #define MAX_MSG 1000;
    
    int new_fd;
    
    int mysighandler(int signo)
    {
         close(new_fd);
         syslog(LOG_DEBUG,"EXIT client program");
         exit(0);
    }
    
    int main(void)
    {
         int sockfd;
         struct sockaddr_in my_addr;
         struct sockaddr_in their_addr;
         socklen_t sin_size;
         struct sigaction sa;
         int yes = 1;
         char mesg[1000]; 
         char mesg1[570];
         static int i = 0;
    
         memset(mesg,0,1000);
         memset(mesg1,0,570);
    
         //     strcpy(mesg1,"HTTP/1.1 200 OK\r\nCONTENT-LENGTH:435\r\nCONTENT-TYPE: text/xml; charset='UTF-8'\r\nSERVER: 'OS/version' UPnP/1.0 'product/version'\r\n\r\n<?xml version='1.0' encoding='UTF-8'?>\r\n<soap-env:Envelope xmlns:soap-env='http://schemas.xmlsoap.org/soap/envelope/'\r\n soap-env:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>\r\n<soap-env:Body>\r\n<m:AuthenticateResponse\r\nxmlns:m='urn:NETGEAT-ROUTER:service:ParentalControl:1'>\r\n</m:AuthenticateResponse>\r\n<ResponseCode>000</ResponseCode>\r\n</soap-env:Body>\r\n</soap-env:Envelope>\r\n\0");
    
         //strcpy(mesg1,"HTTP/1.1 200 OK\r\nCONTENT-LENGTH:435\r\nCONTENT-TYPE: text/xml; charset='UTF-8'SERVER: 'OS/version' UPnP/1.0 'product/version'\r\n\r\n<?xml version='1.0' encoding='UTF-8'?><soap-env:Envelope xmlns:soap-env='http://schemas.xmlsoap.org/soap/envelope/' soap-env:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'><soap-env:Body><m:AuthenticateResponse xmlns:m='urn:NETGEAT-ROUTER:service:ParentalControl:1'></m:AuthenticateResponse><ResponseCode>000</ResponseCode></soap-env:Body></soap-env:Envelope>\r\n\r\n");
    
         //strcpy(mesg1,"HTTP/1.1 200 OK\r\nCONTENT-LENGTH:435\r\nCONTENT-TYPE: text/xml; charset='UTF-8'\r\nSERVER: 'OS/version' UPnP/1.0 'product/version'\r\n\r\n<?xml version='1.0' encoding='UTF-8'?>\r\n<soap-env:Envelope\r\nxmlns:soap-env='http://schemas.xmlsoap.org/soap/envelope/'\r\nsoap-env:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>\r\n<soap-env:Body>\r\n<m:AuthenticateResponse\r\nxmlns:m='urn:NETGEAT-ROUTER:service:ParentalControl:1'>\r\n</m:AuthenticateResponse>\r\n<ResponseCode>000</ResponseCode>\r\n</soap-env:Body>\r\n</soap-env:Envelope>\r\n");
    
         strcpy(mesg1,"HTTP/1.1 200 OK\r\nCONTENT-LENGTH:389\r\nCONTENT-TYPE: text/xml; charset=\"UTF-8\"\r\nSERVER: \"OS/version\" UPnP/1.0 \"product/version\"\r\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<soap-env:Envelope\r\nxmlns:soap-env=\"http://schemas.xmlsoap.org/soap/envelope/\"\r\nsoap-env:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\r\n<soap-env:Body>\r\n<m:AuthenticateResponse\r\nxmlns:m=\"urn:NETGEAT-ROUTER:service:ParentalControl:1\">\r\n</m:AuthenticateResponse>\r\n<ResponseCode>000</ResponseCode>\r\n</soap-env:Body>\r\n</soap-env:Envelope>\r\n");
    
    
    
         syslog(LOG_DEBUG,"Entered into the server program %d",__LINE__);
         
         if((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1)
         {
              perror("socket");
              exit(1);
         }
         
         my_addr.sin_family = AF_INET;
         my_addr.sin_port = htons(MYPORT);
         my_addr.sin_addr.s_addr = inet_addr("192.168.1.1");
         memset(my_addr.sin_zero,'\0',sizeof(my_addr.sin_zero));
         
         if (bind(sockfd,(struct sockaddr*) &my_addr,sizeof(struct sockaddr))== -1)
         {
              perror("bind");
              exit(1);
         }
         
         syslog(LOG_DEBUG,"Entered into the server program %d",__LINE__);
         if (listen(sockfd,BACKLOG) == -1)
         {
              perror("listen");
              exit(1);
         }
    
         signal(SIGUSR1,mysighandler);
         
         
         while(1)
         {
              syslog(LOG_DEBUG,"Entered into the server program %d",__LINE__);
              sin_size = sizeof(struct sockaddr_in);
              if((new_fd = accept(sockfd,(struct sockaddr*)&their_addr,&sin_size)) == -1)
              {
                   perror("accept");
                   continue;
              }
              while(1)
              {
              
                   recv(new_fd,mesg,1000,0);
              
    
                   if(strstr(mesg,"Authenticate") != NULL)
                   {
                        i = 1;
                        send(new_fd,mesg1,570,0);
                        printf("sendign: %s",mesg1);
                   }
    
    
                   memset(mesg,0,1000);
              }
         }
    
         close(new_fd);
         return 0;
    }

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > #define MAX_MSG 1000;
    You should delete the ; and start using your symbolic constants in your code.
    At the moment, it's full of magic numbers.

    > recv(new_fd,mesg,1000,0);
    1. recv() returns a value - pay attention to it
    2. recv() does NOT append a \0, in case you were expecting a string
    3. recv() does NOT reassemble fragmented packets - that's your job
    4. if recv() fills the buffer, there is no room for you to append a \0 (if you wanted to make it a string)

    5. All the use of memset() to clear the buffer is a pointless waste of time, IF you're doing everything else properly (chiefly, paying attention to return results).

    6. The consequence of 3 is that you can't immediately attempt something like strstr() and expect success. You might get only "Authe" in the first packet, and then "nticate" in the next one.


    > send(new_fd,mesg1,570,0);
    Try sending the actual message length, rather than something with a few hundred \0's on the end.

    Again, send() returns a result, which may NOT always be the amount to asked to send. If it's less, then it's YOUR responsibility to attempt to send the remainder.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Code:
    while(1)
              {
               
                   recv(new_fd,mesg,1000,0);
               
     
                   if(strstr(mesg,"Authenticate") != NULL)
                   {
                        i = 1;
                        send(new_fd,mesg1,570,0);
                        printf("sendign: %s",mesg1);
                   }
     
     
                   memset(mesg,0,1000);
              }
    What makes you think the above loop will EVER terminate?
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  4. #4
    Registered User
    Join Date
    Mar 2008
    Location
    India
    Posts
    147
    Salem ,

    Thanks for your points on recv return type .

    But my concern was like , why does it loop around recv infinetly where as it should have stopped for next packet to recive as it recv is blocking call.

    When i run this after reciveing one packet, recv would loop in while(1) for n number of times, my expectation was it should stop once i send a packet.

    brewbuck,

    I was just testing the stuff.so while(1) is not a problem for me at this level.

  5. #5
    Registered User
    Join Date
    Oct 2011
    Location
    Denmark
    Posts
    80
    As Salem said, you should check the return of the recv() and send() functions. If recv() does not block, it probably means that an error has occurred, I would say probably the connection was closed by the client or something like that. And since you do not check the return of the send() function, you are not even sure that your message was really sent.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Avoiding program blocking while recv()
    By trooper in forum Networking/Device Communication
    Replies: 2
    Last Post: 04-05-2011, 04:22 AM
  2. recv() - doesn't block?
    By TheDarkAvenger in forum Networking/Device Communication
    Replies: 1
    Last Post: 06-20-2009, 11:25 AM
  3. block the server
    By luke luvevou in forum C++ Programming
    Replies: 5
    Last Post: 05-12-2009, 09:08 PM
  4. recv from ftp server (winsock2)
    By commissar in forum Networking/Device Communication
    Replies: 2
    Last Post: 03-04-2005, 04:16 AM
  5. Server recv data problem! Please help!
    By hyaku_ in forum Networking/Device Communication
    Replies: 15
    Last Post: 01-28-2005, 02:35 PM