IPv5: 128-bit addresses
DNS system
network OS
distributed OS
sockets: "high-level" abstraction
read
& write
system calls#include <arpa/inet.h>
htons
: host to network short (16 bits)ntohs
: network to host short (16 bits)htonl
: host to network long (32 bits)ntohl
: network to host long (32 bits)```
typedef unint32t inaddrt; struct inaddr { inaddrt s_addr }; ```
string rep (dotted notation) to 32-bit int: inet_aton(char *cp, struct in_addr_t *inp);
number to dotted string: inet_ntoa
API design constrained by limited hardware resources of the 1970s & 1980s
still need to translate the high-level notation into wire format (protocol)
text-based URI: easier on the eyes, harder on the computer
but here we're staring into the nitty gritty
given hostname, get IP address (library call):
/etc/hosts
/etc/host.conf
/etc/nsswitch.conf
obsolete: struct hostent *gethostbyname(char *name)
modern: getaddrinfo
struct addrinfo *
after name lookup, hostname is not used: all connections via IP address
HTTP: higher-level protocol
socket: (Unix) abstraction for all networking
create socket: socket(2)
read
/write
/close
on open socket descriptorssend
/recv
header files (#include
):
sys/types.h
sys/socket.h
socket(2)
returns a freshly-allocated socket object (socket descriptor, file descriptor)
sd = socket(int domain, int type, int protocol)
AF_UNIX
(IPC)AF_INET
(internet protocol--IP)SOCK_RAW
(raw IP packets)SOCK_DATATGRAM
(UDP)SOCK_STREAM
(TCP)2 operating modes: passive (server) & active (client)
server
bind()
: associate socket with port#listen()
: specify operating modeaccept()
: return new socket descriptor for each opened connectionbind()
client
bind()
(optional: if not used, port is assignened by system)connect()
bind()
(optional: use to get return address)sendto()
1.
connect()
send()
bind()
sockaddr
: essentially a base type
sockaddr_in
int accept(int sd, struct sockaddr *addr, socklen_t *addrlen);
addr
& `addrlen are out parameters, filled in with remote addressaddr
may be NULL if you don't carelisten(2)
: set size of backlog for passive sockets
may have multiple concurrent open connections for a given address
text: host:port
address data structure: struct sockaddr
struct sockaddr_in
AF_INET
) (acts as tag on variant recordsin_family
: AF_INET
sin_port
sin_addr
: struct sin_addr {uint32_t s_addr;};
struct struct sockaddr_in
) & cast to struct sockaddr
internet address (TCP/IP or UDP/IP) use struct sockaddr_in
sin_family = AF_INET
(tag field)sin_addr.s_addr = ip_address
(32 bits)sin_port = port
(16 bits)for server, use s_addr = htonl(INADDR_ANY)
use port = 0
for randomly-assigned unused port
connect(int sd, const struct sockaddr *addr, socklen_t addrlen)
addr
client
socket()
bind
() (if response is wanted)sendto()' &
recvfrom()`connect()
followed by send()
& recv()
server
socket()
bind()
recvfrom()
& sendto()
UDP sockets are
either you don't care if some data is lost or you have your own homebrew error recovery scheme
applications:
multicast: TODO: details
client (connectionless)
sendto(sd, msg, len, flags, addr, addrlen)
RTFM for details
TODO: live coding
threads
like all file descriptors, socket descriptor stays open across fork
& exec