title: Client in C++, use gethostbyname or getaddrinfo
body: <p>I found the following code to open a connection in C: </p>
  
  <pre><code>int OpenConnection(const char *hostname, int port)
  {
      int sd;
      struct hostent *host;
      struct sockaddr_in addr = {0};
      if ((host = gethostbyname(hostname)) == NULL)
      {
          perror(hostname);
          abort();
      }
  
      sd = socket(PF_INET, SOCK_STREAM, 0);
  
      addr.sin_family = AF_INET;
      addr.sin_port = htons(port);
      addr.sin_addr.s_addr = *(long *)(host-&gt;h_addr_list[0]);
      if (connect(sd, (struct sockaddr *)&amp;addr, sizeof(addr)) != 0)
      {
          close(sd);
          perror(hostname);
          abort();
      }
      return sd;
  }
  </code></pre>
  
  <p>As I was rewriting this code in C++, I found out that I should be using <code>getaddrinfo</code> instead of <code>gethostbyname</code>, according to a comment in this post: <a href="https://stackoverflow.com/questions/52266584/c-what-does-long-host-h-addr-do">C - What does *(long *)(host-&gt;h_addr); do?</a>. </p>
  
  <p>I was looking at <a href="https://beej.us/guide/bgnet/html/multi/syscalls.html#getaddrinfo" rel="noreferrer">Beej's guide to socket programming</a>, and found the following example:</p>
  
  <pre><code>int status;
  struct addrinfo hints;
  struct addrinfo *servinfo;  // will point to the results
  
  memset(&amp;hints, 0, sizeof hints); // make sure the struct is empty
  hints.ai_family = AF_UNSPEC;     // don't care IPv4 or IPv6
  hints.ai_socktype = SOCK_STREAM; // TCP stream sockets
  hints.ai_flags = AI_PASSIVE;     // fill in my IP for me
  
  if ((status = getaddrinfo(NULL, "3490", &amp;hints, &amp;servinfo)) != 0) {
      fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
      exit(1);
  }
  
  // servinfo now points to a linked list of 1 or more struct addrinfos
  
  // ... do everything until you don't need servinfo anymore ....
  
  freeaddrinfo(servinfo); // free the linked-list
  </code></pre>
  
  <p>However, this example applies to creating a server, which makes me wonder</p>
  
  <p>A] is <code>getaddrinfo</code>supposed to be used for clients</p>
  
  <p>and</p>
  
  <p>B] How would I modify the hints struct and the function parameters in order to make this code suitable for creating a client?</p>
  
  <p>Currently, I have the following code but I</p>
  
  <pre><code>struct addrinfo hints = {0};
  hints.ai_family = AF_UNSPEC;
  hints.ai_socktype = SOCK_STREAM;
  
  struct addrinfo *client_info;
  
  const int status = getaddrinfo(hostname, port, &amp;hints, &amp;client_info); //don't know if its correct
  </code></pre>
  
  <p><strong>Update</strong>:</p>
  
  <p>For anyone who may find it useful, here is my final code after reading the accepted answer:</p>
  
  <pre><code>int OpenConnection(const char *hostname, const char *port)
  {
      struct hostent *host;
      if ((host = gethostbyname(hostname)) == nullptr)
      {
          //More descriptive error message?
          perror(hostname);
          exit(EXIT_FAILURE);
      }
  
      struct addrinfo hints = {0}, *addrs;
      hints.ai_family = AF_UNSPEC;
      hints.ai_socktype = SOCK_STREAM;
      hints.ai_protocol = IPPROTO_TCP;
  
      const int status = getaddrinfo(hostname, port, &amp;hints, &amp;addrs);
      if (status != 0)
      {
          fprintf(stderr, "%s: %s\n", hostname, gai_strerror(status));
          exit(EXIT_FAILURE);
      }
  
      int sfd, err;
      for (struct addrinfo *addr = addrs; addr != nullptr; addr = addr-&gt;ai_next)
      {
          sfd = socket(addrs-&gt;ai_family, addrs-&gt;ai_socktype, addrs-&gt;ai_protocol);
          if (sfd == ERROR_STATUS)
          {
              err = errno;
              continue;
          }
  
          if (connect(sfd, addr-&gt;ai_addr, addr-&gt;ai_addrlen) == 0)
          {
              break;
          }
  
          err = errno;
          sfd = ERROR_STATUS;
          close(sfd);
      }
  
      freeaddrinfo(addrs);
  
      if (sfd == ERROR_STATUS)
      {
          fprintf(stderr, "%s: %s\n", hostname, strerror(err));
          exit(EXIT_FAILURE);
      }
  
      return sfd;
  }
  </code></pre>