Programming with TCP – I Timeline of a Typical Scenario TCP Server Functions socket() bind() listen() accept() TCP 3–Way Handshaking TCP Client Functions connect() TCP 3-way HS – errors
Timeline of a Typical Scenario TCP Client TCP Server socket(); socket(); bind(); Connection establishment connect(); TCP 3–way handshake listen(); write(); accept(); blocks until connection from client read(); process request data (reply) read(); write(); end-of-file notification close(); read(); close();
Timeline of a Typical Scenario The server is started, then sometime later a client is started that connects to the server. Assuming that the client sends a request to the server, the server processes the request & sends a reply back. This continues until the client closes its end of the connection, which sends an end-of-file notification to the server. The server then closes its end of the connection, goes back to accept. See: TCPClient.c & TCPServer.c
TCP Server Functions – socket() & bind() socket(): creates a TCP socket bind() : binds the socket to a well-known port
TCP Server Functions – listen() Performs 2 actions: When a socket is created, it is assumed to be an active socket, i.e. a client socket will issue a connect. The listen function converts an unconnected socket into a passive socket, indicating that the kernel should accept incoming connection requests directed to this socket. In terms of TCP state transition diagram, the call to listen moves the socket from CLOSED state to the LISTEN state.
TCP Server Functions – listen() The second argument to this function specifies the maximum number of connections that the kernel should queue for this socket. To understand the backlog argument, we must realize that for a given listening socket. #include<sys/socket.h> int listen(int sockfd, int backlog); returns: 0 if OK, -1 on failure.
TCP Server Functions – listen() The kernel maintains 2 queues Incomplete connection queue which contains an entry for each SYN that has arrived from a client for which the server is waiting completion of the TCP 3-way handshake. These sockets are in the SYN_RCVD state. A completed connection queue which contains an entry for each client with whom the TCP 3-way handshake has completed. These sockets are in ESTABLISHED state.
TCP Server Functions – listen() accept completed connection queue. (ESTABLISHED state.) incomplete connection queue. (SYN_RCVD state.) SYN Arriving Sum of both queues cannot exceed backlog!
TCP 3–Way Handshaking TCP Client TCP Server connect called SYN j RTT Create an entry on incomplete queue. RTT SYN k, ACK j+1 RTT connect returns ACK k+1 Entry moved from incomplete queue to completed queue. accept can return
TCP 3–Way Handshaking What if this 3rd ACK never arrives? Berkley-derived implementations have a timeout of 75 seconds for these incomplete entries. When the 3–way handshake completes normally, the entry moves from incomplete queue to the end of the complete queue. When the process calls accept, the first entry on the completed queue is returned. If the queue is empty, the process sleeps until an entry arrives.
TCP Server Functions – accept() #include<sys/socket.h> int accept(int sockfd, struct socaddr *clientaddress, socklen_t *addrlen); returns: non-negative descriptor if OK, -1 on failure. accept returns the next completed connection from the front of the completed connection queue. If the completed connection queue is empty, the process is put to sleep. If accept is successful, its return value is a brand new descriptor automatically created by the kernel. A given server typically creates one listening socket which then exists for the lifetime of the server. BUT the kernel creates a connected socket for each client connection that is accepted. When the server is finished serving a given client, the connected socket is closed.
TCP Client Functions – socket() Same as TCP server’s socket().
TCP Client Functions – connect() #include<sys/socket.h> int connect(int sockfd, const struct sockaddr *serveraddress, socklen_t *addrlen); returns: 0 if OK, -1 on failure. connect is used by a TCP client to establish a connection with a TCP server. If client socket is not bound to a specific port/IP before connect is called (as in our example), kernel will first choose an ephemeral port# & source IP.
TCP Client Functions – connect() TCP Client TCP Server connect called SYN j Create an entry on incomplete queue. RTT SYN k, ACK j+1 RTT connect returns ACK k+1 Entry moved from incomplete queue to completed queue. accept can return There are several different errors possible
TCP 3-way HS – errors TCP Client receives no response to its SYN. ETIMEOUT is returned (after a total of 75 seconds). connect called 6 seconds SYN j SYN j 24 seconds . SYN j return ETIMEOUT
TCP 3-way HS – errors If the server’s response to the client’s SYN is a rest (RST) indicating that no process is waiting for connections on the server host at the specified port (i.e. The server process is probably not running). ECONNREFUSED is returned to the client. If connect fails, the socket is no longer usable and must be closed. We cannot call connect again on the socket. In terms of TCP state diagram, connect moves the state from CLOSED to SYN_SENT to ESTABLISHED.