Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
Socket Programming  ›  Lesson

Address Conversion — Text to Binary and Back

Address Conversion 12 minSocket calls need addresses in binary form, so programs parse text with inet_pton, print binary with inet_ntop, and turn host names into ready-made address lists with getaddrinfo.

Address Conversion — Text to Binary and Back

People write 203.0.113.10. Sockets want four raw bytes inside an address structure. Config files, logs and admin screens live in the first world; sendto lives in the second. A small set of functions crosses between them, and the older ones in that set are a classic source of bugs.

The rule

Text in, binary out: pton parses, ntop prints, getaddrinfo resolves names.

The letters decode the names: p is for presentation, the text people read, and n is for network, the binary form sockets use.

  • inet_pton turns text into binary. It returns 1 on success, 0 if the text is not a valid address for the chosen family, and −1 if the family itself is not supported.
  • inet_ntop turns binary back into text, for logs, admin screens and error messages.
  • getaddrinfo takes a host name (or an address written as text) and a port, does any DNS lookup needed, and returns a list of ready-made addresses with every structure already filled in.
struct addrinfo hints = {0}, *res, *p;
hints.ai_family   = AF_UNSPEC;     /* IPv4 or IPv6, whichever exist */
hints.ai_socktype = SOCK_DGRAM;    /* UDP */

if (getaddrinfo("mumbai.manja-arena.example", "7777", &hints, &res) == 0) {
    for (p = res; p != NULL; p = p->ai_next) {
        /* try socket(p->ai_family, ...) and sendto(..., p->ai_addr, p->ai_addrlen) */
    }
    freeaddrinfo(res);             /* the list was allocated for you */
}

Address structures come in different sizes: sockaddr_in for IPv4, sockaddr_in6 for IPv6, and sockaddr_storage, which is big enough for either. That last one is the right type for "whoever just sent me a datagram", when you cannot know in advance which kind it will be.

Avoid the older functions. inet_addr and inet_ntoa handle IPv4 only. inet_addr returns the same value for an error as for the perfectly valid address 255.255.255.255, and inet_ntoa returns a pointer to a static buffer that its next call overwrites.

The shortcut

To turn IPv4 text into bytes by hand, convert each of the four numbers into one byte, in order. The first number goes first on the wire.

198.51.100.4 as bytesStep 1 of 4
  1. 198

    198 = 12 × 16 + 6, so it is hex C6.

Going the other way, inet_ntop reads the bytes in the same order, so C6 33 64 04 prints as 198.51.100.4. If a log ever shows 4.100.51.198 instead, something reversed the bytes along the way: a byte-order bug, which is the subject of the next lesson.

Drills

Answer fast — trust the rule.

quick drill

In inet_pton, what do the "p" and the "n" stand for?

quick drill

Which four bytes does inet_pton produce for 203.0.113.10?

quick drill

inet_pton(AF_INET, "203.0.113.300", &addr) returns 0. What does that mean?

quick drill

Why pass AF_UNSPEC to getaddrinfo when looking up the match server?

quick drill

Why does printf("%s -> %s", inet_ntoa(a), inet_ntoa(b)) print the same address twice?

Remember

  • Text in, binary out: pton parses, ntop prints, getaddrinfo resolves names into a list of addresses.
  • Four numbers become four bytes, first number first.
  • Trap: the old inet_addr and inet_ntoa, which are IPv4-only and full of surprises.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainFrom a name to sendto

Explain how the Manja Arena client should turn mumbai.manja-arena.example and port 7777 into something sendto can use, and why it should not hard-code one IPv4 address or use inet_addr.