Practical Socket C
Practical Socket C
TCP/IP Network
Application
Socket
Socket
TCP/
UDP
TCP/
UDP
IP
Host
IP
Channel
(e.g.
Ethernet)
IP
Router
Channel
Host
2
Ethernet
Frame Format
Host-to-host delivery
(not application-to-application)
IP Address
32-bit identifier
Dotted-quad: 192.118.56.25
www.mkp.com -> 167.208.101.28
Identifies a host interface (not a host)
192.18.22.13
209.134.16.123
5
32 bits
type of
ver head.
len service
length
fragment
16-bit identifier flgs
offset
time to upper
Header
layer
live
checksum
total datagram
length (bytes)
for
fragmentation/
reassembly
data
(variable length,
typically a TCP
or UDP segment)
E.g. timestamp,
record route
taken, specify
list of routers
to visit.
Transport Protocols
Best-effort not sufficient!
Add services on top of IP
User Datagram Protocol (UDP)
Data checksum
Best-effort
source port #
dest port #
length
checksum
Application
data
(message)
32 bits
source port #
dest port #
sequence number
acknowledgement number
head not
UA P R S F
len used
checksum
Receive window
Urg data pnter
counting
by bytes
of data
(not segments!)
# bytes
rcvr willing
to accept
application
data
(variable length)
Ports
Identifying the ultimate destination
IP addresses identify hosts
Host has many applications
Ports (16-bit identifier)
Application
WWW
Port
80
Telnet
25
23
192.18.22.13
10
source
message
segment
Ht
datagram Hn Ht
frame Hl Hn Ht
M
M
M
M
Encapsulation
application
transport
network
link
physical
link
physical
switch
M
Ht
Hn Ht
Hl Hn Ht
destination
Hn Ht
application
transport
network
link
physical
Hl Hn Ht
network
link
physical
Hn Ht
router
Introduction
11
Socket
How does one speak TCP/IP?
Sockets provide interface to TCP/IP
Generic interface for many protocols
A socket is an abstraction through which an
application may send and receive data, in much
the same way as an open file allows an application
to read and write data to the stable storage.
12
Sockets
A socket using the TCP/IP protocol family is
uniquely identified by
end-to-end protocol (TCP or UDP)
Internet address
port number
Logical relationships
among applications,
socket abstractions,
protocols and port
numbers within a
single host
13
Protocol
SOCK_STREAM
IPPROTO_TCP
SOCK_DGRAM
IPPROTO_UDP
Family
TCP
UDP
PF_INET
Socket reference
15
close() function
When an application is finished with a
socket, it calls close()
int close(int socket);
Returns 0 on success
or
-1 on failure
16
Generic
Address structures
IP Specific
struct sockaddr
{
unsigned short sa_family; /* Address family (e.g., AF_INET) */
char sa_data[14];
/* Protocol-specific address information */
};
struct sockaddr_in
{
unsigned short sin_family;
unsigned short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
struct in_addr
{
unsigned long s_addr;
};
/*
/*
/*
/*
sa_family
sockaddr
Family
2 bytes
sockaddr_in
sa_data
Blob
2 bytes
Family
Port
sin_family sin_port
4 bytes
Internet address
sin_addr
8 bytes
Not used
sin_zero
17
19
Server
socket()
TCP ClientServer
bind()
listen()
Client
accept()
(Block until connection)
socket()
Handshake
Data (request)
recv()
send()
close()
send()
Data (reply)
recv()
End-of-File
recv()
connect()
close()
19
socket()
connect()
send()
recv()
close()
22
socket()
connect()
send()
recv()
close()
23
socket()
connect()
send()
recv()
close()
24
socket()
connect()
send()
recv()
close()
25
26
Server side
functions (1)
Server
socket()
bind()
listen()
recv()
close()
27
Server side
functions
(2)
int bind(int socket, struct sockaddr
*localAddress,
unsigned int addressLength)
Server
socket()
bind()
listen()
accept()
(Block until connection)
recv()
send()
recv()
close()
28
Server side
functions (3)
Server
socket()
bind()
listen()
accept()
(Block until connection)
recv()
send()
recv()
close()
29
Server side
functions
(4)
int accept(int
socket, struct sockaddr
*clientAddress,
unsigned
intnext
*addressLength)
accept() dequeues
the
connection on the
Server
socket()
bind()
listen()
accept()
(Block until connection)
recv()
send()
recv()
close()
30
Accepts Connection:
Illustration
pipe
Client A
#1
Original socket
accept
#2
Newly returned socket
pipe
Client B
30
TCP Client/Server
Interaction (1)
Server starts by getting ready to receive client
connections
1.
2.
3.
4.
Client
Create a TCP socket
Establish connection
Communicate
Close the connection
1.
2.
3.
4.
Server
Create a TCP socket
Assign a port to socket
Set socket to listen
Repeatedly:
a. Accept new connection
b. Communicate
c. Close the connection
32
TCP Client/Server
Interaction (2)
/* Create socket for incoming connections */
if ((servSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
DieWithError("socket() failed");
1.
2.
3.
4.
Client
Create a TCP socket
Establish connection
Communicate
Close the connection
1.
2.
3.
4.
Server
Create a TCP socket
Bind socket to a port
Set socket to listen
Repeatedly:
a. Accept new connection
b. Communicate
c. Close the connection 33
TCP Client/Server
Interaction (3)
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,
Server
sizeof(echoServAddr))
Client < 0)
DieWithError("bind() failed");
1. Create a TCP socket
1.
2.
3.
4.
2.
3.
4.
TCP Client/Server
Interaction (4)
/* Mark the socket so it will listen for incoming connections */
if (listen(servSock, MAXPENDING) < 0)
DieWithError("listen() failed");
1.
2.
3.
4.
Client
Create a TCP socket
Establish connection
Communicate
Close the connection
1.
2.
3.
4.
Server
Create a TCP socket
Bind socket to a port
Set socket to listen
Repeatedly:
a. Accept new connection
b. Communicate
c. Close the connection 35
TCP Client/Server
Interaction (5)
for (;;) /* Run forever */
{
clntLen = sizeof(echoClntAddr);
if ((clntSock=accept(servSock,(struct sockaddr
*)&echoClntAddr,&clntLen)) < 0)
DieWithError("accept() failed");
1.
2.
3.
4.
Client
Create a TCP socket
Establish connection
Communicate
Close the connection
1.
2.
3.
4.
Server
Create a TCP socket
Bind socket to a port
Set socket to listen
Repeatedly:
a. Accept new connection
b. Communicate
c. Close the connection 36
TCP Client/Server
Interaction (6)
Server is now blocked waiting for connection from a
client
Later, a client decides to talk to the
server
Server
Client
1.
2.
3.
4.
1.
2.
3.
4.
TCP Client/Server
Interaction (7)
/* Create a reliable, stream socket using TCP */
if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
DieWithError("socket() failed");
1.
2.
3.
4.
Client
Create a TCP socket
Establish connection
Communicate
Close the connection
1.
2.
3.
4.
Server
Create a TCP socket
Bind socket to a port
Set socket to listen
Repeatedly:
a. Accept new connection
b. Communicate
c. Close the connection 38
TCP Client/Server
Interaction (8)
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,
Server
sizeof(echoServAddr))
< 0)
Client
DieWithError("connect() failed");
1. Create a TCP socket
1.
2.
3.
4.
2.
3.
4.
TCP Client/Server
Interaction (9)
if ((clntSock=accept(servSock,(struct sockaddr
*)&echoClntAddr,&clntLen)) < 0)
DieWithError("accept() failed");
1.
2.
3.
4.
Client
Create a TCP socket
Establish connection
Communicate
Close the connection
1.
2.
3.
4.
Server
Create a TCP socket
Bind socket to a port
Set socket to listen
Repeatedly:
a. Accept new connection
b. Communicate
c. Close the connection 40
TCP Client/Server
Interaction (10)
echoStringLen = strlen(echoString);
1.
2.
3.
4.
Client
Create a TCP socket
Establish connection
Communicate
Close the connection
1.
2.
3.
4.
Server
Create a TCP socket
Bind socket to a port
Set socket to listen
Repeatedly:
a. Accept new connection
b. Communicate
c. Close the connection 41
TCP Client/Server
Interaction (11)
/* Receive message from client */
if ((recvMsgSize = recv(clntSocket, echoBuffer, RCVBUFSIZE, 0)) <
0)
DieWithError("recv() failed");
1.
2.
3.
4.
Client
Create a TCP socket
Establish connection
Communicate
Close the connection
1.
2.
3.
4.
Server
Create a TCP socket
Bind socket to a port
Set socket to listen
Repeatedly:
a. Accept new connection
b. Communicate
c. Close the connection 42
TCP Client/Server
Interaction (12)
close(sock);
1.
2.
3.
4.
Client
Create a TCP socket
Establish connection
Communicate
Close the connection
close(clntSocket)
1.
2.
3.
4.
Server
Create a TCP socket
Bind socket to a port
Set socket to listen
Repeatedly:
a. Accept new connection
b. Communicate
c. Close the connection 43
Byte Ordering
Increasing memory address
Address A+1
Little-endian
byte order
Address A
High-order byte
Low-order byte
MSB
Big-endian
byte order
16-bit value
Low-order byte
Address A+1
LSB
High-order byte
Address A
43
44
44
Byte Order
Any time, you pass externally significant
values (i.e. Internet Addresses and
Ports) to an API function in a sockaddr
structure, the implementation expects
those values to be in network byte
order.
In general, you should apply these
conversions as the last operation before
sending the data and as the first
operation after receiving it.
46
Address Conversion
Functions
String to Binary
Binary to String
inet_ntoa is the inverse of inet_addr(),
which we used in the server. It takes the 32bit binary representation of the clients
address and converts it to a dotted-quad
string.
47
50
51
52
53
Socket structure
Addresses
FIFO queues
Additional protocol state
information relevant to the
opening and closing TCP
handshakes (For a TCP socket)
54
56
Bytes to SendQ
SendQ to RecvQ
RecvQ to Delivered
59
Deadlock (1)
SendQ is full
Deadlock (2)
62
Deadlock (3)
63
Deadlock (4)
64
Deadlock (5)
Design the protocol carefully to avoid
simultaneous send()s in both directions
65
Performance Implications
Throughput
66
68
69
70
71
72
73
TCP Tidbits
Client must know the servers address and
port
Server only needs to know its own port
No correlation between send() and recv()
Client Server
send(Hello Bob)
Closing a Connection
Echo Client
Echo Server
send(string)
while (not received entire
string)
recv(buffer)
print(buffer)
close(socket)
recv(buffer)
while(client has not closed
connection)
send(buffer)
recv(buffer)
close(client socket)
75
UDP
76
Characteristics of UDP
sockets
77
UDP Client-Server
Server
socket()
bind()
Client
recvfrom()
socket()
Data (request)
sendto()
sendto()
recvfrom()
Data (reply)
- No handshake
- No simultaneous close
close()
76
Functions (1)
int sendto(int socket, const void *msg, unsigned int
msgLength, int flags, struct sockaddr
*destAddr, unsigned int addrLen)
Functions (2)
int recvfrom(int socket, void *msg, unsigned int
msgLength,
int flags, struct sockaddr *srcAddr,
unsigned
int *addrLen)
UDP Client/Server
Interaction (1)
Server starts by getting ready to receive client
messages
1.
2.
3.
4.
Client
Create a UDP socket
Send a message
Receive a reply
Close
Server
1. Create a UDP socket
2. Assign a port to socket
3. Repeatedly:
a. Wait for message to arrive
b. Reply
81
UDP Client/Server
Interaction (2)
/* Create socket for sending/receiving datagrams */
if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
DieWithError("socket() failed");
1.
2.
3.
4.
Client
Create a UDP socket
Send a message
Receive a reply
Close
Server
1. Create a UDP socket
2. Assign a port to socket
3. Repeatedly:
a. Wait for message to arrive
b. Reply
82
UDP Client/Server
Interaction (3)
/* Construct local address structure */
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 */
/* Bind to the local address */
if (bind(sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) <
O)
DieWithError("bind() failed");
1.
2.
3.
4.
Client
Create a UDP socket
Send a message
Receive a reply
Close
Server
1. Create a UDP socket
2. Assign a port to socket
3. Repeatedly:
a. Wait for message to arrive
b. Reply
83
UDP Client/Server
Interaction (4)
for (;;)
/* Run forever */
{
/* Set the size of the in-out parameter */
cliAddrLen = sizeof(echoClntAddr);
/* Block until receive message from a client */
if ((recvMsgSize = recvfrom(sock, echoBuffer, ECHOMAX, 0,
(struct sockaddr *) &echoClntAddr, &cliAddrLen)) < 0)
DieWithError("recvfrom() failed");
1.
2.
3.
4.
Client
Create a UDP socket
Send a message
Receive a reply
Close
Server
1. Create a UDP socket
2. Assign a port to socket
3. Repeatedly:
a. Wait for message to arrive
b. Reply
84
UDP Client/Server
Interaction (5)
Server is now blocked waiting for messages from a
client
Later, a client decides to talk to the server
1.
2.
3.
4.
Client
Create a UDP socket
Send a message
Receive a reply
Close
Server
1. Create a UDP socket
2. Assign a port to socket
3. Repeatedly:
a. Wait for message to arrive
b. Reply
85
UDP Client/Server
Interaction (6)
/* Create a datagram/UDP socket */
if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
DieWithError( "socket () failed") ;
1.
2.
3.
4.
Client
Create a UDP socket
Send a message
Receive a reply
Close
Server
1. Create a UDP socket
2. Assign a port to socket
3. Repeatedly:
a. Wait for message to arrive
b. Reply
86
UDP Client/Server
Interaction (7)
/* Construct the server address structure */
echoServAddr.sin_family = AF_INET;
/* Internet addr family */
echoServAddr.sin_addr.s_addr = inet_addr(servIP);
/* Server IP
address */
echoServAddr.sin_port = htons(echoServPort); /* Server port */
/* Send the string to the server */
if (sendto(sock, echoString, echoStringLen, 0, (struct sockaddr *)
&echoServAddr, sizeof(echoServAddr)) != echoStringLen)
DieWithError("sendto() sent a different number of bytes than
expected");
1.
2.
3.
4.
Client
Create a UDP socket
Send a message
Receive a reply
Close
Server
1. Create a UDP socket
2. Assign a port to socket
3. Repeatedly:
a. Wait for message to arrive
b. Reply
87
UDP Client/Server
Interaction (8)
/* Send received datagram back to the client */
if (sendto(sock, echoBuffer, recvMsgSize, 0,
(struct sockaddr *) &echoClntAddr, sizeof(echoClntAddr)) !=
recvMsgSize)
DieWithError("sendto() sent a different number of bytes than
expected");
1.
2.
3.
4.
Client
Create a UDP socket
Send a message
Receive a reply
Close
Server
1. Create a UDP socket
2. Assign a port to socket
3. Repeatedly:
a. Wait for message to arrive
b. Reply
88
UDP Client/Server
Interaction (9)
/* Recv a response */
fromSize = sizeof(fromAddr) ;
if ((respStringLen = recvfrom(sock, echoBuffer, ECHOMAX, 0,
(struct sockaddr *) &fromAddr, &fromSize)) != echoStringLen)
DieWithError("recvfrom() failed") ;
1.
2.
3.
4.
Client
Create a UDP socket
Send a message
Receive a reply
Close
Server
1. Create a UDP socket
2. Assign a port to socket
3. Repeatedly:
a. Wait for message to arrive
b. Reply
89
UDP Client/Server
Interaction (10)
close(sock);
1.
2.
3.
4.
Client
Create a UDP socket
Send a message
Receive a reply
Close
Server
1. Create a UDP socket
2. Assign a port to socket
3. Repeatedly:
a. Wait for message to arrive
b. Reply
90
END
91