cs161 2004 Lecture 3 We mostly care about TCP connections: Two sides SYNs establish ISN ACK on highest seqno seen so far FIN when done Why minimize number of connections? 1) too many small packets 2) flow control over time What is a socket? protocol, two endpoints int socket(int domain, int type, int protocol) domain: PF_INET PF_FILE/PF_UNIX PF_INET6 PF_PACKET APPLETALK, IPX... type: SOCK_STREAM (TCP) SOCK_DGRAM (UDP) SOCK_RAW (sniffers) protocol: 0 int bind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen) needed for listening assigned automatically for connecting but can be done explicitly to get a specific local port int listen(int s, int backlog); tells kernel to respond to SYNs set the backlog length used to be for SYNS, now for complete connections (syncookies avoid old need) int accept(int s, struct sockaddr *addr, socklen_t *addrlen) servers returns a NEW socket fill in the address of the other side int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen) clients ECONNREFUSED No one listening on the remote address. ETIMEDOUT Timeout while attempting connection. EINPROGRESS The socket is non-blocking and the connection cannot be completed immediately. It is possible to select(2) or poll(2) for completion by selecting the socket for writing. After select indicates writability, use getsockopt(2) to read the SO_ERROR option at level SOL_SOCKET to determine whether connect completed successfully (SO_ERROR is zero) or unsuccessfully (SO_ERROR is one of the usual error codes listed here, explaining the reason for the failure). int shutdown(int s, int SHUT_RD | SHUT_WR | SHUT_RDWR) int close(int fd) TIMEWAIT - may need to retransmit last ack, new connections that look alike int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen) SO_REUSEADDR: servers, TIMEWAIT SO_KEEPALIVE: send probes to notice disconnects (> 2 hours!) SO_LINGER: controls close() behaviour. Set time for close to fin-handshake IP_TOS: Use to be "low delay" etc, now diffserv and ECN. Don't use. The small request problem: clnt srv / syn -> connect() <- syn/ack listen() \ ack -> accept() (client sees nothing new!) wr() data -> \ <- ack <- data read() ack -> / <- fin close() ack -> / cl() fin -> int fcntl(int fd, int cmd, long arg); non-blocking: fcntl(soc, F_SETFL, O_NONBLOCK) close on exec: fcntl(soc, F_SETFD, 1); int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); int poll(struct pollfd *ufds, unsigned int nfds, int timeout); l03.c: Example code of simple non-blocking loop, plus client code (ftpd) Where is the analogue to the thread state stored? (ctx, passed through cbs) Which sockets must be marked non-blocking? Why check temp fds and the "real" fds array? Why is the call to select() inefficient? Problem here: not tracking highest descriptor General problem: must recopy every time (made worse b/c inout params) Java NIO case study: MegaJogos multi-player game What problem did the developer have? Thread limit: approximately 1,000 threads Does this imply kernel or user threads? Move to NIO, what problem remained? Java NIO intro Channels - File descriptors Buffers. Why a datatype, not just byte[]? Scatter/gather Net and asynch I/O