Chapter 6
|
Transport layer

6.1.3 Berkley Sockets - A standard set of transport primitives used in
Berkley UNIX for TCP and widely ported to other systems, including Windows,
though Microsoft made significant improvements such as changing the spelling of
several functions.
| Primitive | Meaning |
| SOCKET | Create new communication end point in program |
| BIND | Attach a local port address to a socket |
| LISTEN | Open socket to connection requests and define number of queued connections |
| ACCEPT | Block execution until a connection request arrives; server |
| CONNECT | Attempt to establish connection (e.g. to a program blocked at an ACCEPT); client |
| SEND | Send data over a connection (encapsulated within an TCP segment) |
| RECEIVE | Receive data over a connection. |
| CLOSE | Opposite of ACCEPT and CONNECT |
The following example of an echo client/server illustrates the relative ease
that networked applications can be implemented using the Berkley sockets. For a
complete version see TCP Client and
TCP Server. Most languages implement
network operations ad hoc using function libraries, newer languages such as Java
are designed to include networking as part of the language.
// Server
#include <winsock2.h>
void main(void)
{
char buffer[128];
int retval, sinlen;
struct sockaddr_in sin;
SOCKET s, h;
WSAStartup(0x202,&wsaData);
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = htons(888); // Port 888
// SOCK_STREAM is TCP
s = socket(AF_INET, SOCK_STREAM,0);
// Bind socket to local port
bind(s,(struct sockaddr*)&sin,sizeof(sin));
// Listen for 1 connection
listen(s,1);
sinlen = sizeof(sin);
// 1. Block for connection request
h=accept(s,(struct sockaddr*)&sin,&sinlen );
// 2. Block for receive
recv(h,buffer,sizeof(buffer),0);
// 3. Echo what is received
send(h,buffer,strlen(buffer),0);
closesocket(h);
}
|
// Client
#include <winsock2.h>
#include <iostream.h>
void main(int argc, char* argv[])
{
char buffer[128]= "Hello";
int retval;
unsigned int addr=0;
struct sockaddr_in sin;
struct hostent *host;
SOCKET s;
WSAStartup(0x202,&wsaData);
// Assume valid DNS given
host = gethostbyname(argv[1]);
memcpy(&(sin.sin_addr),
host->h_addr,host->h_length);
sin.sin_family = host->h_addrtype;
sin.sin_port = htons(888);
// Create socket port 888
s = socket(AF_INET, SOCK_STREAM,0);
// 1. Block for server accept connection
connect(s, (struct sockaddr*)&sin,sizeof(sin));
// 2. Send "Hello"
send(s,buffer,strlen(buffer)+1,0);
// 3. Block for Receive
recv(s,buffer,sizeof(buffer),0);
// Print what is received
cout << "Received " << buffer << "\n";
closesocket(s);
}
|
// Server import socket |
// Client import socket |
The Internet Transport Protocols (TCP and UDP)
6.4.1 UDP - Datagram service, no flow or congestion control provided, application using UDP must implement.
Basically UDP just adds ports to IP datagram for delivery to the destination application.

Exercise 1 - ARP
|
Exercise 2 - ping
|
Exercise 3 - UDP
|
TCP - Designed to provide reliable end-to-end service over unreliable
network layer. Runs
on hosts communicating via TCP segments encapsulated as data within an IP
packet. IP is a routed protocol for hosts communicating via fully addressed
packets. TCP connection is full-duplex, point-to-point (only two ends) between
two ports appearing as a byte stream to an application similar to reading
a file (no implicit message boundaries though a carriage return can be data).
6.4.2 TCP Protocol
6.4.3 TCP Header (see Fig. 6-29 of text, page 537)
6.4.4 Connection Management
| Host 1 Client | Host 2 Server |
| Send SYN=1 ACK=0 SEQ#=101 | |
| Receive SYN=1 ACK=0 SEQ#=101 Send SYN=1 ACK=1 SEQ#=35 ACK#=102 |
|
| Receive SYN=1 ACK=1 SEQ#=35 ACK#=102 Send SYN=0 ACK=1 ACK#=36 SEQ#=102 |
|
| Receive SYN=0 ACK=1 ACK#=36 SEQ#=102 |
| Host 1 Request Connect by Client | Host 2 Connect Accept by Server | Host 1 Ack Accept by Client |
| TCP: ----- TCP header ----- TCP: TCP: Source port = 1041 TCP: Destination port = 889 TCP: Sequence number = 6001 TCP: Data offset = 24 bytes TCP: Flags = 02 TCP: ..0. .... = (No urgent pointer) TCP: ...0 .... = (No acknowledgment) TCP: .... 0... = (No push) TCP: .... .0.. = (No reset) TCP: .... ..1. = SYN TCP: .... ...0 = (No FIN) TCP: Window = 4096 TCP: Checksum = 7865 (correct) TCP: TCP: Options follow TCP: Maximum segment size = 1024 |
TCP: ----- TCP header ----- TCP: TCP: Source port = 889 TCP: Destination port = 1041 TCP: Sequence number = 40001 TCP: Acknowledge number = 6002 TCP: Data offset = 24 bytes TCP: Flags = 12 TCP: ..0. .... = (No urgent pointer) TCP: ...1 .... = Acknowledgment TCP: .... 0... = (No push) TCP: .... .0.. = (No reset) TCP: .... ..1. = SYN TCP: .... ...0 = (No FIN) TCP: Window = 4096 TCP: Checksum = 5F17 (correct) TCP: TCP: Options follow TCP: Maximum segment size = 1024 |
TCP: ----- TCP header ----- TCP: TCP: Source port = 1041 TCP: Destination port = 889 TCP: Sequence number = 6002 TCP: Acknowledge number = 40002 TCP: Data offset = 24 bytes TCP: Flags = 02 TCP: ..0. .... = (No urgent pointer) TCP: ...1 .... = (No acknowledgment) TCP: .... 0... = (No push) TCP: .... .0.. = (No reset) TCP: .... ..0. = SYN TCP: .... ...0 = (No FIN) TCP: Window = 4096 TCP: Checksum = 7865 (correct) TCP: TCP: Options follow TCP: Maximum segment size = 1024 |
Closing Connection - The connection is closed using a three-way handshake.
| Client | Server |
| Send FIN=1 | |
| Receive FIN=1 but may continue sending DATA or ACK FIN | |
| Receive DATA or ACK FIN |
Exercise 4 - OPEN and CLOSE Connection
|
6.4.5 TCP Transmission Policy 
Exercise 5 - FLOW Control
|
6.4.6 TCP
Congestion Control
Example: A receiver may advertise a window larger than a congested network can support.
At threshold, increase congestion window and threshold by 1 segment
each time a full window is acknowledged (linear increase), growing up to
the receiver flow control window size.
Use slow start till avoidance threshold reached then use
avoidance. Rationale is that congestion probably occurred due to new
sender coming on so available bandwidth is conservatively halved.
6.4.7 TCP Timer Management
If too short timeout, duplicates sent, too long, increased delay waiting for acknowledgment that may never arrive.
TCP averages RTT estimate (Round Trip Time) since delay may vary widely between segments sent. Using an acknowledgment time of M (latest RTT for acknowledged message):
| RTT = aRTT + (1 - a)M |
With a= 7/8, weighting the effect of the estimated RTT more heavily than the most recent time M to determine the new timeout.
Solution is to ignore RTT of any segment that is retransmitted and double
the timeout value until segments are acknowledged prior to timeout. Then
include in RTT calculation.
Receiver then updates window size > 0 which is lost leaving sender and receiver waiting on the other to do something, hence deadlock. Persistence timer goes off causing sender to send probe to receiver, receiver responds with window size.
Document last modified: