Thread: Not letting sockaddr(s) go out of scope

  1. #1
    Registered User
    Join Date
    Sep 2007
    Posts
    7

    Not letting sockaddr(s) go out of scope

    I'm working on a program using static libraries & sockets with a server, and I thought I had it implemented correctly. I went to have it reviewed, since it isn't due for a week. The instructor said my sockaddr's could go out of scope and that I needed "some type of storage that maps file descriptor to the sockaddr pointer". He put a comment by the two lines in 'mysock.c' where it apparently will go out of scope. He mentioned something about creating a static struct to hold the separate data???

    Can someone point me in the right direction/show me what he means? here are my .h/.c files.

    mysock.h
    Code:
    #ifndef MYSOCK_H
    #define MYSOCK_H
    
    int tcp_init_server( const int port );
    int tcp_server_accept( const int sd );
    int tcp_client( const int server_port, const char * host, int * sd );
    
    int fdprintf( const int fd, char * fmt, ... );
    int fdgets(char *s, int size, const int fd );
    int fdclose( const int fd );
    
    #endif
    mysock.c
    Code:
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    /* for protobyname */
    #include <netdb.h>
    /* for socket, bind */
    #include <sys/types.h>
    #include <sys/socket.h>
    /* fd io */
    #include <unistd.h>
    #include <stdarg.h>
    
    int tcp_init_server(const int port)
    {
        int proto_num = getprotobyname ( "tcp" )->p_proto;
        int sd;
        int rc;
        struct sockaddr_in serv; /* this goes out of scope */
    
        sd = socket( PF_INET, SOCK_STREAM, proto_num );
        if ( sd < 0 )
        {
            exit(1);
        }
    
    
        /*
         * setup the sockaddr_in
         */
        serv.sin_family = PF_INET;
        serv.sin_addr.s_addr = htonl ( INADDR_ANY );
        serv.sin_port = htons ( port );
    
        rc = bind( sd, (struct sockaddr *)&serv, sizeof(serv) );
        if ( rc < 0 )
        {
            exit(1);
        }
    
        rc = listen( sd, 10 );
    
        return sd;
    }
    
    int tcp_server_accept(const int sd)
    {
        int sd2;
        struct sockaddr_in cli; /* this goes out of scope */
        socklen_t cli_len = sizeof(cli);
    
        sd2 = accept( sd, (struct sockaddr *)&cli, &cli_len );
        if ( sd2 <= 0 )
        {
            exit(1);
        }
    
        return sd2;
    }
    
    /*
     * input: a file descriptor along with printf style format string
     *          and arguements to match
     * output: processes the format string and arguments then writes the 
     *          data to the input file descriptor
     * return: the number of bytes written
     *
     * notes: hopefully getting identical behavior to do printf
     */
    int fdprintf( const int fd, char * fmt, ... )
    {
        char * buf = NULL;
        int bytes;
        va_list ap;
    
        va_start( ap, fmt );
    
        /* get the number of bytes needed */
        bytes = vsnprintf ( NULL, 0, fmt, ap );
        /* its actually one short */
        ++bytes;
        buf = ( char * ) malloc( sizeof(char) * ( bytes + 1 ) );
        bytes = vsnprintf ( buf, bytes, fmt, ap );
    
        /* write the data */
        write ( fd, buf, bytes );
    
        /* free the data and the va_list */
        va_end( ap );
        free ( buf );
    
        return bytes;
    }
    
    int fdgets(char *s, int size, const int fd )
    {
    	int r = read(fd, s, size);
    	s[r] = 0;
    	return r;
    }
    
    int fdclose( const int fd )
    {
    	return close (fd);
    }
    Thanks in advance!

  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
    Well it would only be a problem if bind() and accept() held onto the pointer beyond the actual call itself.

    Since the manual pages make no mention of this requirement, and all other examples of bind/accept usage that I've ever seen have assumed that the sockaddr_in variable works just fine by being a local, my guess is your instructor needs to explain themselves better.

    Ask them to cite documentation which requires these variables to be static, because at the moment, I think they're just blowing hot air.
    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
    Registered User
    Join Date
    Sep 2007
    Posts
    7
    Right before I read your response, I asked him why. His answer was that he wants to be able to make multiple simultaneous connections. He suggested creating a struct to hold the variables? Does that mean like a struct containing my other struct?

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Again, why would that be a problem?

    If bind() for example wants to preserve some of the information you pass, then it will have (or allocate) it's own resources to manage that, for as many connections as you're allowed to make. If the connection cannot be created, you get an error return.

    The only thing you need to preserve of the call is the return result. You're free to re-use the same sockaddr_in for another connection, or let it go out of scope.

    Whether you store your socket file descriptors in a struct, an array or whatever other data structure you want, that is entirely up to you.
    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.

  5. #5
    Registered User
    Join Date
    Oct 2007
    Posts
    1
    The reason we need to keep track of these structs is the fact that this code belongs in a library, and we don't really have local copies of the structs to keep track of.

    If you're going to post for help, you might as well post a link to the actual assignment:

    http://arioch.unomaha.edu/~jclark/cs...igma_encoding/

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > NOTE: As long as the descriptor for a socket is in use do NOT let the sockaddr(s) go out of scope.
    So is this just your requirement to give the students something else to think about when writing a library (to force them to use malloc for example), and perform resource tracking?
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Getting an error with OpenGL: collect2: ld returned 1 exit status
    By Lorgon Jortle in forum C++ Programming
    Replies: 6
    Last Post: 05-08-2009, 08:18 PM
  2. Post...
    By maxorator in forum C++ Programming
    Replies: 12
    Last Post: 10-11-2005, 08:39 AM
  3. Please Help - Problem with Compilers
    By toonlover in forum C++ Programming
    Replies: 5
    Last Post: 07-23-2005, 10:03 AM
  4. Nested loop frustration
    By caroundw5h in forum C Programming
    Replies: 14
    Last Post: 03-15-2004, 09:45 PM
  5. Question about C# scope rules
    By converge in forum C# Programming
    Replies: 3
    Last Post: 01-30-2002, 06:56 AM