Presentation on theme: "Programming with TCP – I 1. Timeline of a Typical Scenario 2. TCP Server Functions socket() bind() listen() accept() 3. TCP 3–Way Handshaking 4. TCP Client."— Presentation transcript:
Programming with TCP – I 1. Timeline of a Typical Scenario 2. TCP Server Functions socket() bind() listen() accept() 3. TCP 3–Way Handshaking 4. TCP Client Functions socket() connect() 5. TCP 3-way HS – errors
blocks until connection from client Timeline of a Typical Scenario TCP Client TCP Server socket(); bind(); listen(); accept(); read(); process request write(); read(); close(); socket(); connect(); write(); Connection establishment TCP 3–way handshake read(); data (reply) close(); end-of-file notification
Timeline of a Typical Scenario 1. The server is started, then sometime later a client is started that connects to the server. 2. Assuming that the client sends a request to the server, the server processes the request & sends a reply back. 3. This continues until the client closes its end of the connection, which sends an end-of-file notification to the server. 4. 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: 1. 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() 2. 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 int listen(int sockfd, int backlog); returns: 0 if OK, -1 on failure.
TCP Server Functions – listen() The kernel maintains 2 queues 1. 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. 2. 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() SERVER 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 Create an entry on incomplete queue. SYN j connect called SYN k, ACK j+1 ACK k+1 connect returns Entry moved from incomplete queue to completed queue. accept can return RTT
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() 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. #include int accept(int sockfd, struct socaddr *clientaddress, socklen_t *addrlen); returns: non-negative descriptor if OK, -1 on failure.
TCP Client Functions – socket() Same as TCP server’s socket().
TCP Client Functions – connect() 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. #include int connect(int sockfd, const struct sockaddr *serveraddress, socklen_t *addrlen); returns: 0 if OK, -1 on failure.
TCP Client Functions – connect() There are several different errors possible TCP Client TCP Server Create an entry on incomplete queue. SYN j connect called SYN k, ACK j+1 ACK k+1 connect returns Entry moved from incomplete queue to completed queue. accept can return RTT
TCP 3-way HS – errors 1. TCP Client receives no response to its SYN. ETIMEOUT is returned (after a total of 75 seconds). SYN j connect called SYN j 6 seconds SYN j 24 seconds return ETIMEOUT......
TCP 3-way HS – errors 2. 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.