Skip to main content

Beej's Guide to Network Programming

Popularity Report

Total Popularity Score: 0

Loading...
Loading...
Loading...
Loading...
Loading...
Loading...

Rank

Bookmark History

Saved by 9 people (-2 private), first by anonymouse user on 2008-01-24


Public Sticky notes

Highlighted by henrikakselsen

You'll see that the ai_addr field in the struct addrinfo is a pointer to a struct sockaddr. This is where we start getting into the nitty-gritty details of what's inside an IP address structure.

Highlighted by henrikakselsen

oftentimes, a call to getaddrinfo() to fill out your struct addrinfo for you is all you'll need. You will, however, have to peer inside these structs to get the values out, so I'm presenting them here.

Highlighted by henrikakselsen

So if you have declared ina to be of type struct sockaddr_in, then ina.sin_addr.s_addr references the 4-byte IP address (in Network Byte Order).

Highlighted by henrikakselsen

destination address

Highlighted by henrikakselsen

And this is the important bit: a pointer to a struct sockaddr_in can be cast to a pointer to a struct sockaddr and vice-versa. So even though connect() wants a struct sockaddr*, you can still use a struct sockaddr_in and cast it at the last minute!

Highlighted by henrikakselsen

sin_port must be in Network Byte Order (by using htons()

Highlighted by henrikakselsen

struct sockaddr_storage that is designed to be large enough to hold both IPv4 and IPv6 structures.

Highlighted by henrikakselsen

What's important is that you can see the address family in the ss_family field—check this to see if it's AF_INET or AF_INET6 (for IPv4 or IPv6). Then you can cast it to a struct sockaddr_in or struct sockaddr_in6 if you wanna.

Highlighted by henrikakselsen

bunch of functions that allow you to manipulate IP addresses.

Highlighted by henrikakselsen

inet_pton(), converts an IP address in numbers-and-dots notation into either a struct in_addr or a struct in6_addr

Highlighted by henrikakselsen

inet_ntop()

Highlighted by henrikakselsen

try to use getaddrinfo() to get all the struct sockaddr info, instead of packing the structures by hand.

Highlighted by henrikakselsen

The place most people get stuck around here is what order to call these things in.

Highlighted by henrikakselsen

It helps set up the structs you need later on.

Highlighted by henrikakselsen

You give this function three input parameters, and it gives you a pointer to a linked-list, res, of results.

Highlighted by henrikakselsen

The node parameter is the host name to connect to, or an IP address.

Highlighted by henrikakselsen

Next is the parameter service, which can be a port number, like "80", or the name of a particular service

Highlighted by henrikakselsen

Highlighted by henrikakselsen

Finally, the hints parameter points to a struct addrinfo that you've already filled out with relevant information.

Highlighted by henrikakselsen

getaddrinfo(NULL, "3490", &hints, &servinfo)

Highlighted by henrikakselsen

Highlighted by henrikakselsen

servinfo now points to a linked list of 1 or more struct addrinfos

Highlighted by henrikakselsen

Also, you'll see the AI_PASSIVE flag in there; this tells getaddrinfo() to assign the address of my local host to the socket structures. This is nice because then you don't have to hardcode it.

Highlighted by henrikakselsen

getaddrinfo(argv[1], NULL, &hints, &res

Highlighted by henrikakselsen

What you really want to do is use the values from the results of the call to getaddrinfo(), and feed them into socket() directly like this

Highlighted by henrikakselsen

(This is commonly done if you're going to listen() for incoming connections on a specific port

Highlighted by henrikakselsen

Once you have a socket, you might have to associate that socket with a port on your local machine

Highlighted by henrikakselsen

The port number is used by the kernel to match an incoming packet to a certain process's socket descriptor.

Highlighted by henrikakselsen

If you're going to only be doing a connect() (because you're the client, not the server), this is probably be unnecessary.

Highlighted by henrikakselsen

bind(sockfd, res->ai_addr, res->ai_addrlen);

Highlighted by henrikakselsen