TCP & UDP Sockets (Part IV)
CEN 223 – Internet Communication
Assoc. Prof. Dr. Fatih ABUT
Department of Computer Engineering
Çukurova University
Client Server Communication (1)
The transport protocols TCP and UDP were designed to enable communication
between network applications
• Internet host can have several servers running.
• usually has only one physical link to the “rest of the world”
• When packets arrive how does the host identify which packets should go
to which server?
• Ports
• ports are used as logical connections between network applications
16 bit number (65536 possible ports)
• demultiplexing key
identify the application/process to receive the packet
• TCP connection
• source IP address and source port number
• destination IP address and destination port number
• the combination IP Address : Port Number pair is called a Socket
2
Client Server Communication (2)
Port
Port
65536
65536
65535
65535
65534
65534
65533
65533
82 IP 82
81 Network Host
81 Network
80
80 122.34.45.67
79
79
Network Host 78
78
123.45.67.89
SOCKETS
122.34.45.67: 65534
3
3 123.45.67.89:80
2
2
1
1
Client Server Communication (3)
Port
65536
IP Host
65535
65534
65533
HTTP Server with three
active connections (sockets).
IP Network
Active
Active
82 Active
81 IP Host
Listening
80
IP Host/ 79 The HTTP server listens for
Server 78 future connections.
3
2
IP Host
1
Connections
A socket address is the triplet:
{protocol, local-IP, local-port}
example,
{tcp, 130.245.1.44, 23}
A connection is the 5-tuple that completely specifies the two end-points that
comprise a connection:
{protocol, local-IP, local-port, remote-IP, remote-port}
example:
{tcp, 130.245.1.44, 23, 130.245.1.45, 1024}
5
Socket Domain Families
There are several significant socket
domain families:
Internet Domain Sockets (AF_INET)
implemented via IP addresses and port numbers
Unix Domain Sockets (AF_UNIX)
implemented via filenames (similar to IPC “named pipe”)
6
Stream Socket Transaction (TCP Connection)
Server socket()
Client
bind()
socket()
listen()
connect() 3-way handshake
accept()
write() data
read()
data
write()
read()
EOF
close() read() close()
7
SERVER
Create socket
bind a port to the
socket • Connection-oriented
CLIENT socket connections
listen for incoming
Create socket
• Client-Server view
connections
accept an
connect to server's
incoming
port
connection
read from the write to the
connection connection
loop loop
write to the read from the
connection connection
close connection
Server-Side Socket Details
SERVER
int socket(int domain, int type, int protocol)
Create socket
sockfd =
socket(AP_INET, SOCK_STREAM, 0);
bind a port to the int bind(int sockfd, struct sockaddr *server_addr, socklen_t length)
socket bind(sockfd, &server, sizeof(server));
listen for incoming int listen( int sockfd, int num_queued_requests)
connections
listen( sockfd, 5);
accept an
incoming
int accept(int sockfd, struct sockaddr *incoming_address, socklen_t le
connection newfd = accept(sockfd, &client, sizeof(client)); /* BLOCKS */
read from the int read(int sockfd, void * buffer, size_t buffer_size)
connection
read(newfd, buffer, sizeof(buffer));
write to the int write(int sockfd, void * buffer, size_t buffer_size)
connection
write(newfd, buffer, sizeof(buffer));
9
Client-Side Socket Details
CLIENT
Create socket int socket(int domain, int type, int protocol)
sockfd = socket(AF_INET, SOCK_STREAM, 0);
connect to server int connect(int sockfd, struct sockaddr *server_address, socklen_t le
socket
connect(sockfd, &server, sizeof(server)); /* Blocking */
write to the int write(int sockfd, void * buffer, size_t buffer_size)
connection
write(sockfd, buffer, sizeof(buffer));
read from the int read(int sockfd, void * buffer, size_t buffer_size)
connection read(sockfd, buffer, sizeof(buffer));
10
Creating a Socket
#include <sys/types.h>
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
domain is one of the Protocol Families (AF_INET, AF_UNIX, etc.)
type defines the communication protocol semantics, usually defines
either:
SOCK_STREAM: connection-oriented stream (TCP)
SOCK_DGRAM: connectionless, unreliable (UDP)
protocol specifies a particular protocol, just set this to 0 to accept the
default
11
Byte Ordering
Different computer architectures use different byte ordering to
represent/store multi-byte values (such as 16-bit/32-bit integers)
16 bit integer:
Little-Endian (Intel) Big-Endian (RISC-Sparc)
Low Byte Address A High Byte
High Byte Address A+1 Low Byte
12
Byte Order and Networking
Suppose a Big Endian machine sends a 16 bit integer with the value 2:
0000000000000010
A Little Endian machine will understand the number as 512:
0000001000000000
How do two machines with different byte-orders communicate?
Using network byte-order
Network byte-order = big-endian order
Host byte order
Big Endian (IBM mainframes, Sun SPARC) or
Little Endian (x86)
13
Network Byte Order
Conversion of application-level data is left up to the
presentation layer.
Lower-level layers communicate using a fixed byte order
called network byte order for all control data.
TCP/IP mandates that big-endian byte ordering be used for
transmitting protocol information
All values stored in a sockaddr_in must be in network
byte order.
sin_port a TCP/IP port number.
sin_addr an IP address.
14
Network Byte Order Functions
Several functions are provided to allow conversion between host and network
byte ordering,
Conversion macros (<netinet/in.h>)
to translate 32-bit numbers (i.e. IP addresses):
unsigned long htonl(unsigned long hostlong);
unsigned long ntohl(unsigned long netlong);
to translate 16-bit numbers (i.e. Port numbers):
unsigned short htons(unsigned short hostshort);
unsigned short ntohs(unsigned short netshort);
15
Creating a TCP socket
int socket(int family,int type,int proto);
int mysockfd;
mysockfd = socket(AF_INET, SOCK_STREAM,0);
if (mysockfd<0) {
/* ERROR */
}
16
Socket Options (TCP)
setsockopt(), getsockopt()
TCP_KEEPALIVE
idle time before close (2 hours, default)
TCP_MAXRT
set timeout value
TCP_NODELAY
disable Nagle algorithm
won’t buffer data for larger chunk, but sends immediately
//disable Nagle algorithm
int flags = 1;
if (setsockopt(sockfd, SOL_TCP, TCP_NODELAY, (void *)&flags,
sizeof(flags))) {
perror("ERROR: setsocketopt(), TCP_NODELAY");
exit(0);
};
17
Binding to well known address
int mysockfd;
int err;
struct sockaddr_in myaddr;
mysockfd = socket(AF_INET,SOCK_STREAM,0);
myaddr.sin_family = AF_INET;
myaddr.sin_port = htons( 80 );
myaddr.sin_addr = htonl( INADDR_ANY );
err= bind(mysockfd, (sockaddr *) &myaddr,
sizeof(myaddr));
18
Converting Between IP Address formats
From ASCII to numeric
“130.245.1.44” ➔ 32-bit network byte ordered value
inet_aton(…) with IPv4
inet_pton(…) with IPv4 and IPv6
From numeric to ASCII
32-bit value ➔ “130.245.1.44”
inet_ntoa(…) with IPv4
inet_ntop(…) with IPv4 and IPv6
Note – inet_addr(…) obsolete
cannot handle broadcast address “255.255.255.255” (0xFFFFFFFF)
19
IPv4 Address Conversion
int inet_aton( char *, struct in_addr *);
Convert ASCII dotted-decimal IP address to network byte order 32 bit
value. Returns 1 on success, 0 on failure.
char *inet_ntoa(struct in_addr);
Convert network byte ordered value to ASCII dotted-decimal (a string).
20
listen()
int listen( int mysockfd, int backlog);
mysockfd is the TCP socket (already bound to an address)
backlog is the number of incoming connections the kernel should be able to
keep track of (queue for us).
listen() returns -1 on error (otherwise 0).
21
Accepting an incoming connection
Once we call listen(), the O.S. will queue
incoming connections
Handles the 3-way handshake
Queues up multiple connections.
When our application is ready to handle a new
connection, we need to ask the O.S. for the
next connection.
22
accept()
int accept( int mysockfd,
struct sockaddr* cliaddr,
socklen_t *addrlen);
mysockfd is the passive mode TCP socket.
cliaddr is a pointer to allocated space.
addrlen is a value-result argument
must be set to the size of cliaddr
on return, will be set to be the number of used bytes in cliaddr.
accept() return value
accept() returns a new socket descriptor (positive integer) or -1 on error.
After accept returns a new socket descriptor, I/O can be done using the
read() and write() system calls.
23
Closing a Socket Session
int close(int socket);
closes read/write IO, closes socket file descriptor
int shutdown( int socketfd, int mode);
where mode is:
0: no more receives allowed “r”
1: no more sends are allowed “w”
2: disables both receives and sends (but doesn’t close the
socket, use close() for that) “rw”
24
Client Code
TCP clients can call connect() which:
takes care of establishing an endpoint address for the client
socket.
don’t need to call bind first, the O.S. will take care of assigning
the local endpoint address (TCP port number, IP address).
Attempts to establish a connection to the specified server.
3-way handshake
25
connect()
int connect( int sockfd,
const struct sockaddr *server,
socklen_t addrlen);
sockfd is an already created TCP socket.
server contains the address of the server (IP Address and TCP port number)
connect() returns 0 if OK, -1 on error
26
Reading from a TCP socket
int read( int fd, char *buf, int max);
By default read() will block until data is available.
reading from a TCP socket may return less than max bytes
(whatever is available).
27
Writing to a TCP socket
int write( int fd, char *buf, int num);
write might not be able to write all num bytes (on a
nonblocking socket).
Other functions (API)
readn(), writen() and readline() - see man pages
definitions.
28
Example
Client Server communication
Client Network Server
Machine A Machine B
• Web browser and server
• FTP client and server
• Telnet client and server
29
Example – Daytime Server/Client
Application protocol
(end-to-end logical connection)
Daytime client Daytime server
Socket API Socket API
TCP protocol
(end-to-end logical connection)
TCP TCP
IP protocol
(physical connection )
IP IP
MAC-level protocol
(physical connection )
MAC driver MAC driver
Actual data flow MAC = media
Network access control
30
Daytime client ▪ Connects to a daytime server
#include "unp.h" ▪ Retrieves the current date and
int main(int argc, char **argv) time
{ % gettime 130.245.1.44
int sockfd, n; Thu Sept 05 15:50:00 2002
char recvline[MAXLINE + 1];
struct sockaddr_in servaddr;
if( argc != 2 )err_quit(“usage : gettime <IP address>”);
/* Create a TCP socket */
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
err_sys("socket error");
/* Specify server’s IP address and port */
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(13); /* daytime server port */
if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
err_quit("inet_pton error for %s", argv[1]);
31
Daytime client
/* Connect to the server */
if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0)
err_sys("connect error");
/* Read the date/time from socket */
while ( (n = read(sockfd, recvline, MAXLINE)) > 0) {
recvline[n] = 0; /* null terminate */
printf(“%s”, recvline);
}
if (n < 0) err_sys("read error");
close(sockfd);
}
32
Daytime Server ▪ Waits for requests from Client
▪ Accepts client connections
#include "unp.h"
#include <time.h> ▪ Send the current time
▪ Terminates connection and goes
int main(int argc, char **argv) back waiting for more
connections.
{
int listenfd, connfd;
struct sockaddr_in servaddr;
char buff[MAXLINE];
time_t ticks;
/* Create a TCP socket */
listenfd = socket(AF_INET, SOCK_STREAM, 0);
/* Initialize server’s address and well-known port */
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(13); /* daytime server */
/* Bind server’s address and port to the socket */
Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
33
Daytime Server
/* Convert socket to a listening socket */
listen(listenfd, LISTENQ);
for ( ; ; ) {
/* Wait for client connections and accept them */
connfd = accept(listenfd, (SA *) NULL, NULL);
/* Retrieve system time */
ticks = time(NULL);
sprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
/* Write to socket */
write(connfd, buff, strlen(buff));
/* Close the connection */
close(connfd);
}
}
34
UDP Socket Programming
sockfd = socket(AF_INET, SOCK_DGRAM, 0)
SOCK_STREAM (tcp)
No connect(), accept()
Send() → sendto(), recv() → recvfrom()
Sendto() includes target address/port
35
35
UDP: unreliable delivery, no connection
DNS, NFS, SNMP
UDP Client-Server Server
socket()
bind()
Client
recvfrom()
socket()
(Block until
receive
sendto() datagram)
Data (request)
recvfrom() sendto()
Data (reply)
close()
- No “handshake”
- No simultaneous close