Thread: Socket Programming

  1. #1
    Registered User
    Join Date
    May 2008
    Location
    Australia
    Posts
    230

    Socket Programming

    Hi there, I'm currently trying to learn sockets, but as a beginner, I still have confusion over pointers. I've been following this online guide:

    http://www.beej.us/guide/bgnet/outpu...age/bgnet.html

    Anyways I'm having confusion with some of the functions etc. An example is this, which is found in the guide:

    Code:
    connect(sockfd, (struct sockaddr *)&dest_addr, sizeof dest_addr);
    The part that confuses me is the
    Code:
    (struct sockaddr *)&dest_addr
    . According to what I've learnt so far, ( ) is for typecasting, so what exactly is that saying? I mean, to be honest, I have no idea.. &dest_addr means the address of that variable, I get that much. * is to dereference a pointer, to get the value of the thing it's pointing too, I get that too. But to dereference a pointer doesn't it have to be at the START of the pointer, not the end? i.e *Pointer not Pointer *, which is what is used in the above example. So as you can probably tell I'm pretty confused, and if anyone could shed some light on this that'd be great, thanks a lot!

    Another thing, if anyone knows of a more beginner friendly socket guide, that'd be great. Something that doesn't rely on an experienced knowledge of C, as I'm still learning, topics such as pointers confuse me, but I feel as if I have the basics down. Ok thanks a lot guys!

  2. #2
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    Yes, that's correct.

    However, struct sockaddr * would be a pointer to a struct sockaddr

    You'll probably see in the manual, http://www.hmug.org/man/2/connect.php that connect() expects a pointer to a struct sockaddr but dest_addr is a struct sockaddr_in. Hence the cast.

    http://www.beej.us/guide/bgnet/outpu...ddr_inman.html tells you the difference between the two.

    These are the basic structures for all syscalls and functions that deal with internet addresses. In memory, the struct sockaddr_in is the same size as struct sockaddr, and you can freely cast the pointer of one type to the other without any harm, except the possible end of the universe.

    Just kidding on that end-of-the-universe thing...if the universe does end when you cast a struct sockaddr_in* to a struct sockaddr*, I promise you it's pure coincidence and you shouldn't even worry about it.

    So, with that in mind, remember that whenever a function says it takes a struct sockaddr* you can cast your struct sockaddr_in* to that type with ease and safety.

    ...

  3. #3
    Registered User
    Join Date
    Apr 2007
    Location
    Sydney, Australia
    Posts
    217
    Quote Originally Posted by pobri19 View Post
    Hi there, I'm currently trying to learn sockets, but as a beginner, I still have confusion over pointers. I've been following this online guide:

    http://www.beej.us/guide/bgnet/outpu...age/bgnet.html

    Anyways I'm having confusion with some of the functions etc. An example is this, which is found in the guide:

    Code:
    connect(sockfd, (struct sockaddr *)&dest_addr, sizeof dest_addr);
    The part that confuses me is the
    Code:
    (struct sockaddr *)&dest_addr
    . According to what I've learnt so far, ( ) is for typecasting, so what exactly is that saying? I mean, to be honest, I have no idea.. &dest_addr means the address of that variable, I get that much. * is to dereference a pointer, to get the value of the thing it's pointing too, I get that too. But to dereference a pointer doesn't it have to be at the START of the pointer, not the end? i.e *Pointer not Pointer *, which is what is used in the above example. So as you can probably tell I'm pretty confused, and if anyone could shed some light on this that'd be great, thanks a lot!

    Another thing, if anyone knows of a more beginner friendly socket guide, that'd be great. Something that doesn't rely on an experienced knowledge of C, as I'm still learning, topics such as pointers confuse me, but I feel as if I have the basics down. Ok thanks a lot guys!
    In this situation "*" is not being used to get the value of the pointer, its being used within the type cast to tell the compiler which type of pointer to cast it to.

  4. #4
    Registered User
    Join Date
    May 2008
    Location
    Australia
    Posts
    230
    Quote Originally Posted by zacs7 View Post
    Yes, that's correct.

    However, struct sockaddr * would be a pointer to a struct sockaddr

    You'll probably see in the manual, http://www.hmug.org/man/2/connect.php that connect() expects a pointer to a struct sockaddr but dest_addr is a struct sockaddr_in. Hence the cast.

    http://www.beej.us/guide/bgnet/outpu...ddr_inman.html tells you the difference between the two.
    So why doesn't it just say:

    connect(sockfd, struct sockaddr *dest_addr, sizeof dest_addr)

    instead of:

    connect(sockfd, (struct sockaddr *)&dest_addr, sizeof dest_addr)

  5. #5
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    Code:
    connect(sockfd, struct sockaddr *dest_addr, sizeof dest_addr)
    Is invalid for one.

    As you know, pointers hold addresses to certain things (they have a type so you know what they point to),

    ie: char * test;

    test is a pointer to a character (it holds the address of a character).

    connect() expects the address of a struct sockaddr, since sockaddr and sockaddr_in are the same in size, and it's perfectly fine to cast one to the other you can do so.

    &dest_addr will give you the address of dest_addr, you then use must cast this address to a struct sockaddr * (pointer) as connect() expects.

    It's the same as writing:

    Code:
    struct sockaddr_in dest_addr;
    struct sockaddr_in * pointerToDestAddr = &dest_addr;  /* a pointer to dest_addr of type sockaddr_in */
    
                    /* cast the pointer to sockaddr, so the compiler knows what you're pointing to */
    connect(sockfd, (struct sockaddr *)pointerToDestAddr, sizeof dest_addr);
    Basically, a simplified version:

    Code:
    #include <stdio.h>
    
    struct a_s
    {
        int something;
    };
    
    struct b_s
    {
        int value;
    };
    
    void foo(struct b_s * blah)
    {
        printf("&#37;d\n", blah->value);
    }
    
    int main(void)
    {
        struct a_s dest_addr;
        struct b_s tmp;
    
        foo(&dest_addr);  /* This is illegal, incompatible pointer types -- a_s is different from b_s as expected by foo() */
    
        /* legal */
        foo((struct b_s *) &dest_addr);
    
        /* also legal (essentially the same thing) */
        tmp = (struct b_s) dest_addr;
        foo(&tmp);
    
        return 0;
    }
    You can see foo() expects a pointer to a struct b_s, but you have a struct a_s -- thus you must cast the pointer or the object.

    Be careful, this doesn't work all the time (in this example it does, sizeof(struct a_s) == sizeof(struct b_s)) and they both have the same type & # of elements.

    I hope I cleared it up.
    Last edited by zacs7; 06-01-2008 at 04:38 AM.

  6. #6
    Registered User
    Join Date
    May 2008
    Location
    Australia
    Posts
    230
    I'm not going to lie, I'm still really confused, but I think it's my lack of knowledge on casting that may be the problem, not your explanation above. Maybe you could try and explain to me what exactly "(struct sockaddr *)&dest_addr" does when passed to connect() in easy to understand terms :P, sorry, and thanks for trying lol, i'm doing my best to understand

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    A cast just basically changes the type to the compiler.
    Code:
    int a = 0;
    short b = (short)a;
    Data is stored as raw in memory, so the compiler relies on the type of the variable to know what data is stored in the memory. This is especially important to know with pointers. We're just telling the compiler to treat the data as a different type:
    Code:
    int a;
    int* b = &a;
    short* c = (short*)b;
    We're telling the compiler basically, the data stored at the location stored in b is short, not int and saves it in variable c.

    Code:
    void foo(int* a) { }
    int main()
    {
        short a;
        foo((int*)&a);
        /* Is equalient to... */
        short b;
        short* c = &b;
        int* d = (int*)c;
        foo(d);
        /* In other words, first take address of b and store in c.
        Then take the address stored in c and store in d.
        We also need to tell the compiler (or assure it) that the data
        stored at the location stored in c is really an int and not a short.
        That's what we use a cast for.
        Then we can safely pass the data to foo. */
    }
    I do hope that example gives you a better understanding.
    (This is an unsafe practice example, but it's meant to help you understand what's going on and nothing else.)
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. socket programming question, closing sockets...
    By ursula in forum Networking/Device Communication
    Replies: 2
    Last Post: 05-31-2009, 05:17 PM
  2. Socket Help - Multiple Clients
    By project95talon in forum C Programming
    Replies: 5
    Last Post: 11-17-2005, 02:51 AM
  3. when to close a socket
    By Wisefool in forum Networking/Device Communication
    Replies: 5
    Last Post: 11-02-2003, 10:33 AM
  4. problem closing socket
    By Wisefool in forum Networking/Device Communication
    Replies: 2
    Last Post: 10-29-2003, 12:19 PM
  5. socket newbie, losing a few chars from server to client
    By registering in forum Linux Programming
    Replies: 2
    Last Post: 06-07-2003, 11:48 AM