Thread: Questions about sockets and structs

  1. #1
    Registered User
    Join Date
    Jun 2018
    Posts
    14

    Questions about sockets and structs

    Hi, I wrote this code
    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netdb.h>
    
    
    int main() {
        char buffer[1000] = "";
        int fd = socket(AF_INET, SOCK_STREAM, 0);
        perror("socket");
        int i = 0, connfd;
        struct addrinfo *hints;
        struct addrinfo *res = malloc(sizeof(res));
        struct sockaddr *incoming;
        res->ai_addr = malloc(sizeof(res->ai_addr));
        hints->ai_flags = AI_PASSIVE;
        hints->ai_family = AF_INET;
        hints->ai_socktype = SOCK_STREAM;
        i = getaddrinfo(NULL, "80", hints, &res);
        perror("getaddrinfo");
        for(i = 0; i < 1; i++) {
            printf("%c", res->ai_addr->sa_data[i]);
        }
        i = bind(fd, res->ai_addr, res->ai_addrlen);
        perror("bind");
        listen(fd, 5);
        socklen_t sizeofIncoming = sizeof(incoming);
        while(connfd = accept(fd, incoming, &sizeofIncoming)) {
            perror("accept");
            read(connfd, buffer, sizeof(buffer));
            write(connfd, "HTTP/1.1 200 OK\nContent-Length: 29\nContent-Type: text/html\n\n", 65);
            sprintf(buffer, "Your ip is: %s", incoming->sa_data);
            write(connfd, buffer, 24);
            printf("SA_DATA\n%s", incoming->sa_data);
            printf("END OF SA_DATA\n");
            close(connfd);
        }
    
    
        return 0;
    }
    I have four questions
    1) Why do I have to malloc *res but not *hints? When I tried to access *res variables it gave seg fault error
    2) Why the line
    Code:
     printf("%c", res->ai_addr->sa_data[i]);
    doesn't print anything? is sa_data empty? why? isn't it supposed to contain an ip address?
    3) In the lines
    Code:
    sprintf(buffer, "Your ip is: %s", incoming->sa_data);
    write(connfd, buffer, 24);
    I try to write "Your ip is: *some ip*" but the browser shows "YourYour ip is: keep-alive"
    Also, what snprintf prints as incoming->sa_data differs from what
    Code:
    printf("SA_DATA\n%s", incoming->sa_data);
    prints
    4) if I change *hints into hints, change all the hints-> to hints. and in the getaddrinfo put a & before hints, it stops working why?

    Thanks in advanced

  2. #2
    Registered User
    Join Date
    Feb 2019
    Posts
    866
    I recoment you to read this Beej guide to network programming

  3. #3
    Registered User
    Join Date
    Jun 2018
    Posts
    14
    Quote Originally Posted by flp1969 View Post
    I recoment you to read this Beej guide to network programming
    I read some of it, it doesn't answer my questions.
    1) is a about the language, not network programming
    2) the guide says sa_data should contain a protocol address, but it doesn't
    3) the same as two, except sa_data contains something but not an address
    4) is about the language, not network programming

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,658
    Well considering all your malloc sizes are wrong, and that beej's examples manage to do it without using malloc at all, perhaps you ought to pay attention.
    System Calls or Bust
    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
    May 2012
    Location
    Arizona, USA
    Posts
    778
    1) Why do I have to malloc *res but not *hints? When I tried to access *res variables it gave seg fault error
    You don't have to malloc res. Read the Beej's guide for examples of how to use getaddrinfo().

    2) Why the line
    Code:
     printf("%c", res->ai_addr->sa_data[i]);
    doesn't print anything? is sa_data empty? why? isn't it supposed to contain an ip address?
    3) In the lines
    Code:
    sprintf(buffer, "Your ip is: %s", incoming->sa_data);
    write(connfd, buffer, 24);
    I try to write "Your ip is: *some ip*" but the browser shows "YourYour ip is: keep-alive"
    Also, what snprintf prints as incoming->sa_data differs from what
    Code:
    printf("SA_DATA\n%s", incoming->sa_data);
    prints
    sa_data is not a string. It's a raw data type. Use inet_ntop() to convert it to a human-readable string. Beej's guide has example code to do that too.

    4) if I change *hints into hints, change all the hints-> to hints. and in the getaddrinfo put a & before hints, it stops working why?
    Your original code doesn't allocate memory for hints or even initialize it, so it's pointing to who knows where, so you're overwriting some memory that you may or may not have access to. hints doesn't have to be a pointer; you just have to pass its address to getaddrinfo().

  6. #6
    Registered User
    Join Date
    Feb 2019
    Posts
    866
    Quote Originally Posted by qqsszz View Post
    I read some of it, it doesn't answer my questions.
    1) is a about the language, not network programming
    2) the guide says sa_data should contain a protocol address, but it doesn't
    3) the same as two, except sa_data contains something but not an address
    4) is about the language, not network programming
    My sugestion was about your code... It is ALL wrong and you should study this well writen simplified guide.
    But... be my guest and I wish you good luck...

  7. #7
    Registered User
    Join Date
    Jun 2018
    Posts
    14
    ok, ok, I will read the guide haha
    But you haven't answered my first question (and that wasn't about networking). Why I don't need to allocate memory for the pointer if it is more than likely pointing to something outside of the program's limits? As far I as know when I do hints->ai_flags, it should segfault, but it doesn't.

    Also, do you have any recommended guide to learn error handling?
    Last edited by qqsszz; 04-17-2019 at 07:37 PM.

  8. #8
    Registered User
    Join Date
    Feb 2019
    Posts
    866
    Quote Originally Posted by qqsszz View Post
    ok, ok, I will read the guide haha
    But you haven't answered my first question (and that wasn't about networking). Why I don't need to allocate memory for the pointer if it is more than likely pointing to something outside of the program's limits? As far I as know when I do hints->ai_flags, it should segfault but it doesn't, but it doesn't.

    Also, do you have any recommended guide to learn error handling?
    Because getaddinfo() will returnt (in the last argument) the pointer of a linked list allocated by itself.
    Notice the prototype:
    Code:
    int getaddrinfo(const char *node, const char *service,
                    const struct addrinfo *hints,
                    struct addrinfo **res);
    That's why you need to call freeaddrinfo() afterwards.

    About 'hints' you don't need to declare as a pointer:

    Code:
    struct addrinfo hints = { .ai_flags = ... };
    And the third arguments is passed as &hints.

    But in your code you don't need to call getaddrinfo!
    Last edited by flp1969; 04-17-2019 at 07:42 PM.

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,323
    Quote Originally Posted by qqsszz
    Why I don't need to allocate memory for the pointer if it is more than likely pointing to something outside of the program's limits?
    You do need to cause the pointer to point to something valid.

    Quote Originally Posted by qqsszz
    As far I as know when I do hints->ai_flags, it should segfault but it doesn't, but it doesn't.
    That's undefined behaviour: it might work for you, then mysteriously fail when you're demonstrating your program to your big boss.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Registered User
    Join Date
    Jun 2018
    Posts
    14
    Quote Originally Posted by flp1969 View Post
    Because getaddinfo() will returnt (in the last argument) the pointer of a linked list allocated by itself.
    Notice the prototype:
    Code:
    int getaddrinfo(const char *node, const char *service,
                    const struct addrinfo *hints,
                    struct addrinfo **res);
    That's why you need to call freeaddrinfo() afterwards.

    About 'hints' you don't need to declare as a pointer:

    Code:
    struct addrinfo hints = { .ai_flags = ... };
    And the third arguments is passed as &hints.

    But in your code you don't need to call getaddrinfo!
    I think you misunderstood the question because I forgot to mention which pointer. I was talking about hints, not res.
    And I don't understand why you say I don't need to call getaddrinfo, I took that part of the code from here System Calls or Bust. I don't know what to give to bind if I don't call getaddrinfo

    Quote Originally Posted by laserlight View Post
    You do need to cause the pointer to point to something valid.


    That's undefined behaviour: it might work for you, then mysteriously fail when you're demonstrating your program to your big boss.
    Thanks

  11. #11
    Registered User
    Join Date
    Feb 2019
    Posts
    866
    @qqsszz, you are trying to create a server for connections, so your code will bind to 0.0.0.0, the address of your network interface or 127.0.0.1. getaddrinfo() is used to query DNS (or hosts file) to translate a NAME to an IP address. For your purposes you don't need this. An example of getaddrinfo() usage:

    Code:
    #include <stdlib.h>
    #include <stdio.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <netdb.h>
    
    int main ( void )
    {
      // I'll try to get debian.org IP addresses...
      char *name = "debian.org";
      struct addrinfo *res, *p;
      struct addrinfo hint = { .ai_flags = AI_PASSIVE,
                               .ai_family = AF_INET,
                               .ai_socktype = SOCK_STREAM,
                               .ai_protocol = IPPROTO_TCP };
      int status;
    
      // getaddrinfo() returns 0 if success.
      if ( status = getaddrinfo ( name, NULL, &hint, &res ) )
      {
        // perror() will not work here!
        fprintf ( stderr, "getaddrinfo: %s\n", gai_strerror ( status ) );
        return EXIT_FAILURE;
      }
    
      // res is a linked list allocated by getaddrinfo!
      for ( p = res; p; p = p->ai_next )
      {
        char buffer[16];  //           1111111
                          //  1234567890123456
                          // "xxx.xxx.xxx.xxx\0"
    
        if ( ! inet_ntop ( AF_INET,
                           & ( ( struct sockaddr_in * ) p->ai_addr )->sin_addr,
                           buffer, sizeof buffer ) )
        {
          perror ( "inet_ntop" );
          freeaddrinfo ( res );
          return EXIT_FAILURE;
        }
    
        printf ( "Found: %s\n", buffer );
      }
    
      // Need to free the linked list!
      freeaddrinfo ( res );
    
      return EXIT_SUCCESS;
    }
    And yes... I was talking about res AND hints, as I show above.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. a few questions about sockets
    By alansandbucket in forum Linux Programming
    Replies: 5
    Last Post: 06-23-2015, 10:58 AM
  2. Two quick questions (learning about data structs)
    By loot in forum C Programming
    Replies: 7
    Last Post: 06-30-2012, 10:28 AM
  3. some basic questions about pointers and structs...
    By brack in forum C Programming
    Replies: 4
    Last Post: 10-16-2010, 09:18 AM
  4. sockets: Why does server[buffer] > client[message]? + more questions
    By heras in forum Networking/Device Communication
    Replies: 4
    Last Post: 03-10-2008, 04:19 AM
  5. Sockets, questions.
    By Vber in forum C Programming
    Replies: 2
    Last Post: 12-26-2002, 12:18 AM

Tags for this Thread