socket send() exits app unexceptively

This is a discussion on socket send() exits app unexceptively within the C Programming forums, part of the General Programming Boards category; Hello everyone, I'm messing with a tiny webserver. A problem arises when I access this webserver with Firefox. When the ...

  1. #1
    UT2004 Addict Kleid-0's Avatar
    Join Date
    Dec 2004
    Posts
    656

    socket send() exits app unexceptively

    Hello everyone, I'm messing with a tiny webserver. A problem arises when I access this webserver with Firefox. When the webserver is done sending all of the data to Firefox, the last send(), at which should release -1 if an error occured:
    http://www.die.net/doc/linux/man/man3/send.3.html
    Doesn't, and instead it closes my application :(

    The webserver does not close, everything goes OK, when I access the webserver with Konqueror or Epiphany web browsers. For some reason Firefox likes to kill the webserver with the send() function!

    Here's a code snip:
    Code:
    puts( "*** WE'RE GOING TO MAKE IT!!" );
    assert((z=send(cs,b,strlen(b),0))!=-1);
    puts( "*** PHEW!!" );
    printf("Sent %d bytes\n",z);
    Here's the overall output:
    Code:
    HTTP server running, please visit http://localhost:60001
    Press a key to exit...
    Foreign User: 127.0.0.1
    Received:
    /*****************************************************
    GET / HTTP/1.1
    Host: localhost:60001
    User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8b2) Gecko/10134297 Firefox/1.0.4
    Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
    Accept-Language: en-us,en;q=0.5
    Accept-Encoding: gzip,deflate
    Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
    Keep-Alive: 300
    Connection: keep-alive
    
    \*****************************************************
    *** WE'RE GOING TO MAKE IT!!
    *** PHEW!!
    Sent 17 bytes
    *** WE'RE GOING TO MAKE IT!!
    *** PHEW!!
    Sent 25 bytes
    *** WE'RE GOING TO MAKE IT!!
    *** PHEW!!
    Sent 2 bytes
    *** WE'RE GOING TO MAKE IT!!
    *** PHEW!!
    Sent 59 bytes
    *** WE'RE GOING TO MAKE IT!!
    *** PHEW!!
    Sent 67 bytes
    *** WE'RE GOING TO MAKE IT!!
    *** PHEW!!
    Sent 28 bytes
    *** WE'RE GOING TO MAKE IT!!
    *** PHEW!!
    Sent 22 bytes
    Foreign User: 127.0.0.1
    Received:
    /*****************************************************
    GET /favicon.ico HTTP/1.1
    Host: localhost:60001
    User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8b2) Gecko/10134297 Firefox/1.0.4
    Accept: image/png,*/*;q=0.5
    Accept-Language: en-us,en;q=0.5
    Accept-Encoding: gzip,deflate
    Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
    Keep-Alive: 300
    Connection: keep-alive
    
    \*****************************************************
    *** WE'RE GOING TO MAKE IT!!
    *** PHEW!!
    Sent 17 bytes
    *** WE'RE GOING TO MAKE IT!!
    *** PHEW!!
    Sent 25 bytes
    *** WE'RE GOING TO MAKE IT!!
    *** PHEW!!
    Sent 2 bytes
    *** WE'RE GOING TO MAKE IT!!
    *** PHEW!!
    Sent 59 bytes
    *** WE'RE GOING TO MAKE IT!!
    *** PHEW!!
    Sent 67 bytes
    *** WE'RE GOING TO MAKE IT!!
    Notice the end where the webserver screams: "WE'RE GOING TO MAKE IT!!", well, they didn't make it :(....*cries*....

    Here's the updated webserver code.
    http://killall.no-ip.org/Programming...ocktail_sauce/

    Does anybody have any hints of why send() kills the webserver unexpectively at the very end of sending data to Firefox ? :(

    PS: Tell me if I should post all of the code onto the forum in text.

  2. #2
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,505
    > assert((z=send(cs,b,strlen(b),0))!=-1);
    NEVER put code inside assert statements - you turn off debug, and that's it - bye bye code.

    When asserts are active, you get exactly that - the program exits - no questions asked. When you run the code in the debugger, then the assert is trapped and it allows you to look around to see what went wrong.

    Besides, your code needs to cope with a return of -1 as well, you can't just dismiss it as being erroneous.

    Asserts are for checking for programming errors, not allowable status returns from functions.
    Eg.
    Code:
    int squareroot ( int x ) {
      assert ( x >= 0 );  // a pre-condition
      // some code
      assert( result * result == x );  // a post-condition
      return result;
    }
    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.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  3. #3
    Registered User
    Join Date
    Jul 2005
    Location
    Transcarpathia
    Posts
    49
    if the connection is terminated, and send() is called, program gets SIGPIPE.
    by default, that signal terminates the program. Either handle that signal, or ignore it.

  4. #4
    UT2004 Addict Kleid-0's Avatar
    Join Date
    Dec 2004
    Posts
    656
    Yeah I don't think there's one instance in my code that was using assert appropriately lol.

    http://killall.no-ip.org/Programming...cktail_sauce.c
    ----
    [edit]
    aaahh valenok, you have a sharp eye on your docs :], thank you,
    Code:
    signal(SIGPIPE, SIG_IGN);
    does the trick :]

    ...VERY excellent, I just tried it! Here's the new snippet:
    Code:
    puts( "*** WE'RE GOING TO MAKE IT!!" );
    if((z=send(cs,b,strlen(b),0))==-1){
       puts("Error sending data to foreign user!");
       if(errno=EPIPE)
       {
          puts("Recovering from the foreign socket termination...");
          break;
       }
       close(cs);
       close(ls);
       return 1;
    }
    puts( "*** PHEW!!" );
    printf("Sent %d bytes\n",z);
    Last edited by Kleid-0; 07-19-2005 at 07:02 AM.

  5. #5
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    >>if(errno=EPIPE)
    Oops, don't you need 2 equals signs in there
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  6. #6
    UT2004 Addict Kleid-0's Avatar
    Join Date
    Dec 2004
    Posts
    656
    Oh jeez lol

  7. #7
    UT2004 Addict Kleid-0's Avatar
    Join Date
    Dec 2004
    Posts
    656
    Alright five days later I've come up with a better solution. Instead of:
    Code:
    signal(SIGPIPE, SIG_IGN);
    if((z=send(cs,b,strlen(b),0))==-1){
      puts("Error sending data to foreign user!");
      if(errno==EPIPE)
      {
        puts("Recovering from the foreign socket termination...");
        break;
      }
      close(cs);
      close(ls);
      return 1;
    }
    You could just go like this:
    Code:
    /* Notice there is no need to ignore the signal pipe because of the send() flag MSG_NOSIGNAL */
    if((z=send(cs,b,strlen(b),MSG_NOSIGNAL))==-1){
      puts("Error sending data to foreign user!");
      if(errno==EPIPE)
      {
        puts("Recovering from the foreign socket termination...");
        break;
      }
      close(cs);
      close(ls);
      return 1;
    }
    I believe that's a cleaner way to prevent your application from being destroyed by the SIG_PIPE signal.

  8. #8
    Registered User
    Join Date
    Jul 2005
    Location
    Transcarpathia
    Posts
    49
    I suggest not using linuxisms. MSG_NOSIGNAL is one of them.
    The more portable code is, the better.

  9. #9
    UT2004 Addict Kleid-0's Avatar
    Join Date
    Dec 2004
    Posts
    656
    How can you tell if this stuff is portable or not? How can you tell they're flags just for linux and not for a different OS too?

  10. #10
    Registered User
    Join Date
    Jul 2005
    Location
    Transcarpathia
    Posts
    49
    by reading standards, and by actually building programs on different platforms.
    you may go to http://www.freebsd.org/cgi/man.cgi
    there are man pages for many OSes. in your case, check every function first before use.
    Read SUS, POSIX - you can find specs in Internet.
    Get C ISO standard. Try to use standard functions and parameters only.
    Get Richard Stevens' books, they help greatly writing good portable code for UNIX systems.
    Build your programs on BSD, Linux, Solaris, Windows, and you get a good coverage.
    Use free compile farms.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Socket Send Help
    By cloudy in forum Networking/Device Communication
    Replies: 2
    Last Post: 11-13-2007, 03:17 PM
  2. sending n no of char data uning send() function,
    By thebrighter in forum Windows Programming
    Replies: 1
    Last Post: 08-22-2007, 12:26 PM
  3. Socket or send() problem?
    By Achy in forum C Programming
    Replies: 5
    Last Post: 06-09-2006, 01:09 PM
  4. send zip file via socket
    By WaterNut in forum C Programming
    Replies: 11
    Last Post: 05-24-2005, 11:49 AM
  5. CString conversion for socket send()
    By WaterNut in forum C++ Programming
    Replies: 13
    Last Post: 04-27-2005, 04:55 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21