% lec 18: sockets # administrivia hw 3 due tomorrow ex15 due Friday # designated initializers in C ```c struct addrinfo { int ai_flags; /* input flags */ int ai_family; /* protocol family for socket */ int ai_socktype; /* socket type */ ... }; ``` ```c /* designated initializer: C only */ struct addrinfo hints = { .ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM }; ``` ```c++ /* C/C++ */ struct addrinfo hints = {0}; hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; ``` # today's plan review client sockets server sockets # send a file over network client: `read` file from disk & `write` data to socket (ex15) ``` {.ditaa #l18/send} +--------------+ +--------------+ | client | | server | +--------------+ +--------------+ ^ | ^ | read | | write read | | write | v | v +--------------+ +--------------+ | kernel | | kernel | +--------------+ +--------------+ ^ | ^ | | v | v +-----+ +-----+ +-----+ +-----+ | {s} | | NIC | | NIC | | {s} | +-----+ +--+--+ +--+--+ +-----+ | ^ | packets | +-----------------------+ ``` # layering applications don't worry about packet reordering/loss using TCP ![courtesy / modified from Wikipedia](l18/encap.svg) # caching client-side `write` ensures data reaches server? server-side `write` ensures data reaches disk? . . . N - data reaches a kernel buffer when `write` returns # client sockets recap DNS: `getaddrinfo`/`freeaddrinfo` `socket`, `connect`, `close` `read` (or `recv`), `write` (or `send`) # server sockets imagine a Q&A session with a group of people step 1: find a place to stand (so people can see you) step 2: say you're ready to go step 3: take a question from the audience . . . ```c /* bind a name to a socket */ int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); /* listen for connections */ int listen(int sockfd, int backlog); /* accept a connection */ int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); ``` # server sockets overview ``` {.ditaa #l18/flow} +-------------------+ | socket(...) -> fd | +-------------------+ | v +-------------------+ | bind(fd, ...) | +-------------------+ | v +-------------------+ | listen(fd, ...) | +-------------------+ | v +-------------------+ newfd +------------------------+ +--------------+ | accept(fd, ...) | -------> | read/write(newfd, ...) | --> | close(newfd) | +-------------------+ +------------------------+ +--------------+ | v +-------------------+ | close(fd) | +-------------------+ ``` # echo server [example: echosrv.c](l18/echosrv.c.html) # bind ```c int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); ``` port < 1024 requires root (linux CAP_NET_BIND_SERVICE) `SO_REUSEADDR` # listen ```c int listen(int sockfd, int backlog); ``` `backlog`: hint for the number of pending connections # accept ```c int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); ``` `addr`, `addrlen`: client address pass NULL if you don't need them # server architectures our echo server: one connection at a time how to talk to multiple clients at the same time? . . . virtualization - next week: processes & threads multiplexing - this Friday: event-driven see [C10K](http://www.kegel.com/c10k.html) # zero copy send a file over network & bypass userspace `write` with `mmap` `sendfile` ```c ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count); ``` # more on HTTP how to decide the length of request/response: close the connection, Content-Length field, or chunked transfer encoding one HTTP request outstanding per TCP connection server push see [HTTP/2](http://en.wikipedia.org/wiki/HTTP/2)