29
Transmission Control Protocol (TCP)

Transmission Control Protocol (TCP). TCP: Overview RFCs: 793, 1122, 1323, 2018, 2581 r reliable, in-order byte steam: m no “message boundaries” r send

Embed Size (px)

Citation preview

Transmission Control Protocol (TCP)

TCP: Overview RFCs: 793, 1122, 1323, 2018, 2581

reliable, in-order byte steam: no “message

boundaries” send & receive buffers

buffer incoming & outgoing data

flow controlled: sender will not

overwhelm receiver congestion controlled:

sender will not overwhelm network

point-to-point (unicast): one sender, one receiver

connection-oriented: handshaking (exchange of

control msgs) init’s sender, receiver state before data exchange

State resides only at the END systems – Not a virtual circuit!

full duplex data: bi-directional data flow in

same connection (A->B & B->A in the same connection)

MSS: maximum segment size

socketdoor

T C Psend buffer

T C Preceive buffer

socketdoor

segm ent

applica tionwrites data

applica tionreads data

TCP segment structure

source port # dest port #

32 bits

applicationdata

(variable length)

sequence number

acknowledgement numberReceive window

Urg data pnterchecksum

FSRPAUheadlen

notused

Options (variable length)

URG: urgent data (generally not used)

ACK: ACK #valid

PSH: push data now(generally not used)

RST, SYN, FIN:connection estab(setup, teardown

commands)

# bytes rcvr willingto accept

countingby bytes of data(not segments!)

Internetchecksum

(as in UDP)

TCP Connection-oriented demux TCP socket identified by 4-tuple:

source IP address source port number dest IP address dest port number

receiving host uses all four values to direct segment to appropriate socket

TCP Demultiplexing Example

ClientIP:B

P

client IP: A

P1P

serverIP: C

SP: 80

DP: 9157

SP: 9157

DP: 80

SP: 80

DP: 5775

SP: 5775

DP: 80

P P

Connection Termination

Reliable, In-OrderData Exchange

Connection Establishment

Typical TCP TransactionClient Server

timetime

A TCP Transaction consists of 3 Phases1. Connection

Establishment Handshaking between

client and server

2. Reliable, In-Order Data Exchange Recover any lost data

through retransmissions and ACKs

3. Connection Termination Closing the connection

TCP Connection Establishment

TCP sender, receiver establish “connection” before exchanging data segments

initialize TCP variables: seq. #s buffers, flow control info (e.g. RcvWindow)

client: connection initiator Socket clientSocket = new Socket("hostname", port#);

server: contacted by client Socket connectionSocket = welcomeSocket.accept();

Connection Establishment (cont)

Host A Host B

SYN, Seq=42

SYN+ACK, Seq=79, ACK=43

ACK, Seq=43, ACK=80

time

Three-way handshake

Three way handshake:

Step 1: client host sends TCP SYN segment to server specifies a random

initial seq # no data

Step 2: server host receives SYN, replies with SYNACK segment server allocates buffers specifies server initial

seq. #Step 3: client receives

SYNACK, replies with ACK segment, which may contain data

time

Connection

requesthost ACKs and selects its own initial seq #

host ACKs

Connection Establishment (cont)

Host A Host B

SYN, Seq=42

SYN+ACK, Seq=79, ACK=43

ACK, Seq=43, ACK=80

time

Three-way handshake

time

Connection

requesthost ACKs and selects its own initial seq #

host ACKs

Seq. #’s: byte stream “number” of

first byte in segment’s data

ACKs: seq # of next byte

expected from other side cumulative ACK

TCP Starting Sequence Number Selection

Why a random starting sequence #? Why not simply choose 0? To protect against two incarnations of the same connection

reusing the same sequence numbers too soon

That is, while there is still a chance that a segment from an earlier incarnation of a connection will interfere with a later incarnation of the connection

How? Client machine seq #0, initiates connection to server with seq

#0. Client sends one byte and client machine crashes Client reboots and initiates connection again Server thinks new incarnation is the same as old connection

TCP Connection Termination

Closing a connection:

client closes socket: clientSocket.close();

Step 1: client end system sends TCP FIN control segment to server

Step 2: server receives FIN, replies with ACK. Server might send some buffered but not sent data before closing the connection. Server then sends FIN and moves to Closing state.

client

FIN

server

ACK

ACK

FIN

close

Datawrite

closed

tim

ed w

ait

close

ACK

DATA

TCP Connection TerminationStep 3: client receives FIN, replies with

ACK.

Enters “timed wait” - will respond with ACK to received FINs

Step 4: server, receives ACK. Connection closed.

Why wait before closing the connection?

If the connection were allowed to move to CLOSED state, then another pair of application processes might come along and open the same connection (use the same port #s) and a delayed FIN from an earlier incarnation would terminate the connection.

client

FIN

server

ACK

ACK

FIN

closing

closing

closedti

med w

ait

closed

CLOSED

LISTEN

SYN_RCVD SYN_SENT

ESTABLISHED

CLOSE_WAIT

LAST_ACKCLOSING

TIME_WAIT

FIN_WAIT_2

FIN_WAIT_1

Passive open Close

Send/ SYNSYN/SYN + ACK

SYN + ACK/ACK

SYN/SYN + ACK

ACK

Close /FIN

FIN/ACKClose /FIN

FIN/ACKACK + FIN/ACK

Timeout after two segment lifetimes

FIN/ACK

ACK

ACK

ACK

Close /FIN

Close

CLOSED

Active open /SYN

TCP State-Transition Diagram

Typical TCP Client/Server Transitions

TCP clientlifecycle

TCP serverlifecycle

How to program using the TCP?

TCP UDPIPLLPL

Socket Layer

TCP UDPIPLLPL

Socket LayerTCP UDP

IPLLPL

Socket Layer

Socket Layer: Programmer’s API to

the protocol stack

Typical network app has two pieces: client and server Server: Passive entity. Provides service to clients

e.g., Web server responds with the requested Web page

Client: initiates contact with server (“speaks first”) typically requests service from server, e.g., Web Browser

Socket Creation

Family Type Protocol

TCPPF_INET

SOCK_STREAM IPPROTO_TCP

UDP SOCK_DGRAM IPPROTO_UDP

mySock = socket(family, type, protocol); UDP/TCP/IP-specific sockets

Socket reference File (socket) descriptor in UNIX Socket handle in WinSock

TCP Client/Server Interaction

Client1. Create a TCP socket2. Establish connection3. Communicate4. Close the connection

Server1. Create a TCP socket2. Assign a port to socket3. Set socket to listen4. Repeatedly:

a. Accept new connectionb. Communicatec. Close the connection

Server starts by getting ready to receive client connections…

TCP Client/Server Interaction

Client1. Create a TCP socket2. Establish connection3. Communicate4. Close the connection

Server1. Create a TCP socket2. Bind socket to a port3. Set socket to listen4. Repeatedly:

a. Accept new connectionb. Communicatec. Close the connection

/* Create socket for incoming connections */ if ((servSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) DieWithError("socket() failed");

TCP Client/Server Interaction

Client1. Create a TCP socket2. Establish connection3. Communicate4. Close the connection

Server1. Create a TCP socket2. Bind socket to a port3. Set socket to listen4. Repeatedly:

a. Accept new connectionb. Communicatec. Close the connection

echoServAddr.sin_family = AF_INET; /* Internet address family */ echoServAddr.sin_addr.s_addr = htonl(INADDR_ANY);/* Any incoming interface */ echoServAddr.sin_port = htons(echoServPort); /* Local port */

if (bind(servSock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0) DieWithError("bind() failed");

TCP Client/Server Interaction

Client1. Create a TCP socket2. Establish connection3. Communicate4. Close the connection

Server1. Create a TCP socket2. Bind socket to a port3. Set socket to listen4. Repeatedly:

a. Accept new connectionb. Communicatec. Close the connection

/* Mark the socket so it will listen for incoming connections */ if (listen(servSock, MAXPENDING) < 0) DieWithError("listen() failed");

TCP Client/Server Interaction

Client1. Create a TCP socket2. Establish connection3. Communicate4. Close the connection

Server1. Create a TCP socket2. Bind socket to a port3. Set socket to listen4. Repeatedly:

a. Accept new connectionb. Communicatec. Close the connection

for (;;) /* Run forever */{ clntLen = sizeof(echoClntAddr);

if ((clntSock=accept(servSock,(struct sockaddr *)&echoClntAddr,&clntLen)) < 0) DieWithError("accept() failed");

TCP Client/Server Interaction

Client1. Create a TCP socket2. Establish connection3. Communicate4. Close the connection

Server1. Create a TCP socket2. Bind socket to a port3. Set socket to listen4. Repeatedly:

a. Accept new connectionb. Communicatec. Close the connection

Server is now blocked waiting for connection from a client

TCP Client/Server Interaction

Client1. Create a TCP socket2. Establish connection3. Communicate4. Close the connection

Server1. Create a TCP socket2. Bind socket to a port3. Set socket to listen4. Repeatedly:

a. Accept new connectionb. Communicatec. Close the connection

Later, a client decides to talk to the server…

TCP Client/Server Interaction

Client1. Create a TCP socket2. Establish connection3. Communicate4. Close the connection

Server1. Create a TCP socket2. Bind socket to a port3. Set socket to listen4. Repeatedly:

a. Accept new connectionb. Communicatec. Close the connection

/* Create a reliable, stream socket using TCP */ if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) DieWithError("socket() failed");

TCP Client/Server Interaction

Client1. Create a TCP socket2. Establish connection3. Communicate4. Close the connection

Server1. Create a TCP socket2. Bind socket to a port3. Set socket to listen4. Repeatedly:

a. Accept new connectionb. Communicatec. Close the connection

echoServAddr.sin_family = AF_INET; /* Internet address family */ echoServAddr.sin_addr.s_addr = inet_addr(servIP); /* Server IP address */ echoServAddr.sin_port = htons(echoServPort); /* Server port */

if (connect(sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0) DieWithError("connect() failed");

TCP Client/Server Interaction

Client1. Create a TCP socket2. Establish connection3. Communicate4. Close the connection

Server1. Create a TCP socket2. Bind socket to a port3. Set socket to listen4. Repeatedly:

a. Accept new connectionb. Communicatec. Close the connection

echoStringLen = strlen(echoString); /* Determine input length */

/* Send the string to the server */ if (send(sock, echoString, echoStringLen, 0) != echoStringLen) DieWithError("send() sent a different number of bytes than expected");

TCP Client/Server Interaction

Client1. Create a TCP socket2. Establish connection3. Communicate4. Close the connection

Server1. Create a TCP socket2. Bind socket to a port3. Set socket to listen4. Repeatedly:

a. Accept new connectionb. Communicatec. Close the connection

/* Receive message from client */ if ((recvMsgSize = recv(clntSocket, echoBuffer, RCVBUFSIZE, 0)) < 0) DieWithError("recv() failed");

TCP Client/Server Interaction

Client1. Create a TCP socket2. Establish connection3. Communicate4. Close the connection

Server1. Create a TCP socket2. Bind socket to a port3. Set socket to listen4. Repeatedly:

a. Accept new connectionb. Communicatec. Close the connection

close(sock); close(clntSocket)

TCP Tidbits

Clientsend(“Hello Bob”)

recv() -> “Hi Jane”

Server

recv() -> “Hello ”recv() -> “Bob”send(“Hi ”)send(“Jane”)

Client knows server address and port No correlation between send() and recv()