Beej’s Guide

Intro

  • Get a socket with socket() and use it with send() and recv(). read() and write() work too but don’t give you as much control.
  • Internet sockets vs. UNIX sockets? (doc)
    • Internet sockets have TCP overhead, UNIX domain sockets don’t
  • Three types of IP (or UNIX sockets): stream, datagram, raw
  • What does a connection mean, concretely?
  • ::1 is the IPv6 loopback address.
  • IPv4 uses 32 bits, v6 uses 128 bits
  • Port numbers are a TCP thing
  • Endianness is a concern; the network byte order is always big-endian, the host byte order could be either. Assume the host order is wrong and always convert data going in/out. htons() is “host-to-network short”, and ntohs() is the opposite. You can replace s for l (long)

getaddrinfo

  • The sockaddr struct is hard to work with directly, so you can sub in sockaddr_in or sockaddr_in6 instead. Not sure how this works exactly, because the memory layouts are different.
  • inet_pton() converts a string IP address into a in_addr, inet_ntop() does the reverse. Stands for “presentation-to-network” and “network-to-presentation”.
  • IPv6 isn’t compatible / doesn’t need NAT (TIL!)
  • This API is pretty frustrating tbh! getaddrinfo returns a linked list of addrinfo structs, each containing a sockaddr. You can’t use the sockaddr directly though, it’s just an abstraction around more specific types of socket addresses. You have to look at af_family from the addrinfo and either cast the sockaddr to sockaddr_in or sockaddr_in6, and use THAT in the call to inet_ntop. 😬
    • None of this seems well-documented, to make things worse!
    • The Rust interface is SO much nicer for this

(PAUSED TO GET A BIT MORE FOUNDATIONAL INFO FROM Linux programming interface)

Edit