0

In all the example including Beej's Guide, the IP address is provided in dot notation and then it's fed to ::getaddrinfo(). This post doesn't answer my question.

After which the addrinfo struct is used for socket related functions (e.g. connect(), bind(), listen()). For example:

struct addrinfo hints, *res;
// ... create socket etc.
connect(sockfd, res->ai_addr, res->ai_addrlen);

Example
The variable ai_addr is of type sockaddr which can be safely typecasted to sockaddr_storage, sockaddr_in and sockaddr_in6.

Question:

If I typecast sockaddr to sockaddr_in (or sockaddr_in6)

sockaddr_in& ipv4 = (sockaddr_in&)(sockaddr_variable);

and feed below info:

  • ipv4.sin_family = AF_INET
  • ipv4.sin_addr = [IP Address in net byte order]
  • ipv4.sin_port = [Port number in net byte order]

Can I call the connect() method directly using above info?

connect(sockfd, &ipv4, sizeof(ipv4));

With my program it doesn't appear to work. Am I missing something, or is there a better way?

The motivation behind is that, if we have the information of IPAddress, Port etc. in socket readable format then why to go through the cycle of getaddrinfo()

Community
  • 1
  • 1
iammilind
  • 68,093
  • 33
  • 169
  • 336
  • sin_addr & sin_port should have the values in network byte order. Do use the function htonl & htons to convert it? – dvasanth Aug 09 '14 at 16:39

3 Answers3

2

Be sure you're placing your values in network order, here's a small example:

#include<stdio.h>
#include<sys/socket.h>
#include<arpa/inet.h>

int main(int argc, char *argv[])
{
    int sock;
    struct sockaddr_in server;

    sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock == -1)
    {
        printf("Could not create socket\n");
    }
    printf("Socket created\n");

    server.sin_family = AF_INET;
    // 173.194.32.207 is a google address
    server.sin_addr.s_addr = 173 | 194 << 8 | 32 << 16 | 207 << 24;
    server.sin_port = 0x5000; // port 80

    if (connect(sock, (struct sockaddr *)&server, sizeof(server)) < 0)
    {
        perror("connect failed. Error");
        return 1;
    }

    printf("Connected\n");

    close(sock);
    return 0;
}
ccKep
  • 5,786
  • 19
  • 31
  • It was indeed in network byte order. Due to `<>` in the question, it got disappeared. I have replaced that with `[]`. However your answer suggests that it's possible, which means, I might be making a mistake. – iammilind Aug 09 '14 at 16:49
  • The code up there is a fully compilable example, so without any other code from your end / actual values you're using we can't be sure what the problem is. – ccKep Aug 09 '14 at 16:51
  • htons() and htonl() allow portable conversion to network byte order. This will matter when you port your code to a future processor architecture. – Richard Hodges Aug 09 '14 at 18:10
0

First check whether the machine is reachable & the server application is running on the machine using "netstat" utility. Use inet_aton method to convert dotted address to network byte order. Finally, log the error value returned by the connect to get the exact reason of failure.

dvasanth
  • 1,337
  • 1
  • 9
  • 10
0

It's worth noting that calling socket::{connect, bind, ...} is wrong: these are C APIs and C doesn't have namespaces, classes and so on.

You should use getaddrinfo as it's much easier and safer to use. But nothing prevents you from using struct sockaddr and all its variants. Indeed, getaddrinfo is a sort of wrapper as stated in man(3) getaddrinfo:

The getaddrinfo() function combines the functionality provided by the gethostbyname(3) and getservbyname(3) functions into a single interface, but unlike the latter functions, getaddrinfo() is reentrant and allows programs to eliminate IPv4-versus-IPv6 dependen‐ cies.

An example:

#include <sys/socket.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main()
{
   struct sockaddr_in addr = {0};
   addr.sin_family = AF_INET;
   addr.sin_port   = htons(80);

  inet_pton(addr.sin_family, "198.252.206.16", &addr.sin_addr);

  int fd = socket(addr.sin_family, SOCK_STREAM, 0);

  if (fd == -1)
       ; /* could not create socket */

  if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
        ;  /* could not connect */

   close(fd);

}
edmz
  • 8,220
  • 2
  • 26
  • 45