TCP/IP Sockets in
TCP/IP Network
Relationships among the protocols, applications and
the sockets API in the hosts and routers, as well as
the flow of data from one application to another.
Application
Application
Socket
Socket
TCP/
UDP
TCP/
UDP
IP
Host
IP
Channel
(e.g.
Ethernet)
IP
Router
Channel
Host
2
Ethernet
Frame Format
Internet Protocol (IP)
Datagram (packet) protocol
Best-effort service
Loss
Reordering
Duplication
Delay
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
IPv4 datagram format
IP protocol version
number
header length
(bytes)
type of data
max number
remaining hops
(decremented at
each router)
upper layer protocol
to deliver payload to
how much overhead
with TCP?
20 bytes of TCP
20 bytes of IP
= 40 bytes + app
layer overhead
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
32 bit source IP address
32 bit destination IP address
Options (if any)
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
Transmission Control Protocol (TCP)
Data checksum
Reliable byte-stream delivery
Flow and congestion control
7
UDP Datagram format
32 bits
Length, in
bytes of UDP
segment,
including
header
source port #
dest port #
length
checksum
Application
data
(message)
UDP segment format
8
TCP segment structure
URG: urgent data
(generally not used)
ACK: ACK #
valid
In 32 bit words
PSH: push data now
(generally not used)
RST, SYN, FIN:
connection estab
(setup, teardown
commands)
Internet
checksum
(as in UDP)
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
Options (variable length)
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
E-mail
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
Applications may refer to many sockets
Sockets accessed by many applications
Logical relationships
among applications,
socket abstractions,
protocols and port
numbers within a
single host
13
TCP/IP Sockets (1)
int mySock = socket(family, type, protocol);
Nonnegative=success
-1=failure
PF_INET (IPv4), PF_INET6 (IPv6), PF_UNIX (local Unix)
TCP/IP-specific sockets
Type
Protocol
SOCK_STREAM
IPPROTO_TCP
SOCK_DGRAM
IPPROTO_UDP
Family
TCP
UDP
PF_INET
Socket reference
File (socket) descriptor in UNIX
Socket handle in WinSock
14
TCP/IP Sockets (2)
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;
};
/*
/*
/*
/*
Internet protocol (AF_INET) */
Port (16-bits) */
Internet address (32-bits) */
Not used */
/* Internet address (32-bits) */
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
Clients and Servers (1)
Client: Initiates the connection
Server: Passively waits to respond
18
Clients and Servers (2)
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
Addresses and Sockets
Structure to hold address
information
Functions pass address from user to
OS
bind()
connect()
sendto()
Functions pass address from OS to user
accept()
recvfrom()
20
Client side functions (1)
int socket(int protocolFamily, int type, int
protocol)
Nonnegative=success
-1=failure
PF_INET - internet protocol family.
SOCK_STREAM socket with reliable bytestream
SOCK_DGRAM best-effort datagram socket.
The constant IPPROTO_TCP) for a stream
socket
The constant (IPPROTO_UDP) for a datagram
socket.
socket()
connect()
send()
recv()
close()
Supplying the constant 0 as the third
parameter requests the default end-to-end
protocol for the specified protocol
22
Client side functions (2)
int connect(int socket, struct sockaddr
*foreignAddress,
unsigned int addressLength)
socket descriptor created by socket ().
foreignAddress pointer to a sockaddr because
the sockets API is generic; for our purposes, it
will always be a pointer to a sockaddr_in
containing the Internet address and port of the
server.
addressLength length of the address structure
and is invariably given as sizeof(struct
sockaddr_in).
return 0 on success and -1 on failure.
socket()
connect()
send()
recv()
close()
When connect() returns, the socket is
connected and communication can proceed.
23
Client side functions (3)
int send(int socket, const void *msg,
unsigned int msgLength, int flags)
socket descriptor for the connected
socket through which data is to be sent
Msg points to the message to send
msgLength length (bytes) of the
message.
The default behavior for send() is to block
until all of the data is sent
flags provides a way to change the
default behavior of the socket call.
0 default behavior
Returns the number of bytes sent or
-1 for failure.
socket()
connect()
send()
recv()
close()
24
Client side functions (4)
int recv(int socket, void *rcvBuffer,
unsigned int bufferLength, int flags)
socket descriptor for the connected socket
through which data is to be received
rcvBuffer points to the buffer--that is, an area
in memory such as a character array--where
received data will be placed
bufferLength gives the length of the buffer,
which is the maximum number of bytes that
can be received at once.
The default behavior for recv() is to block until
at least some bytes can be transferred.
Flags provides a way to change the default
behavior of the socket call.
0 default behavior
Returns the number of bytes received
or
-1 for failure.
socket()
connect()
send()
recv()
close()
25
Client side functions (5)
When an application is finished with a
socket, it calls close()
int close(int socket);
socket()
Returns 0 on success
connect()
or
send()
-1 on failure
recv()
close()
26
Server side
functions (1)
int socket(int protocolFamily,
int type, int protocol)
Server
socket()
bind()
listen()
PF_INET - internet protocol family
SOCK_STREAM socket with reliable byteaccept()
stream
(Block until connection)
SOCK_DGRAM best-effort datagram socket
The constant IPPROTO_TCP for a stream
socket
recv()
The constant IPPROTO_UDP for a datagram
socket
send()
Supplying the constant 0 as the third
parameter requests the default end-to-end
protocol for the specified protocol
recv()
close()
27
Server side
functions
(2)
int bind(int socket, struct sockaddr
*localAddress,
unsigned int addressLength)
socket descriptor returned by an earlier call
to socket().
localAddress pointer to a sockaddr, but for
TCP/IP applications, it will actually point to a
sockaddr_in containing the Internet address of
the local interface and the port to listen on.
addressLength length of the address
structure, invariably passed as sizeof(struct
sockaddr_in)
Returns 0 on success and -1 on failure.
The Internet address can be set to the special
wildcard value INADDR_ANY, which means
that connections to the specified port will be
directed to this socket, regardless of which
Internet address they are sent to; this practice
can be useful if the host happens to have
multiple Internet addresses.
Server
socket()
bind()
listen()
accept()
(Block until connection)
recv()
send()
recv()
close()
28
Server side
functions (3)
int listen(int socket, int
queueLimit)
l i s t e n ( ) causes internal state
changes to the given socket, so that
incoming TCP connection requests
will be handled and then queued for
acceptance by the program.
socket descriptor returned by an
earlier call to socket().
queueLimit specifies an upper
bound on the number of incoming
connections that can be waiting at
any time.
Returns 0 on success and -1 on
failure.
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
queue for socket.
If the queue is empty, accept() blocks until a
connection request arrives.
When successful, accept() fills in the sockaddr
structure, pointed to by clientAddress, with the
address of the client at the other end of the
connection
addressLength specifies the maximum size of the
clientAddress address structure and contains the
number of bytes actually used for the address
upon return.
If successful, accept() returns a descriptor for a
new socket that is connected to the client. The
socket sent as the first parameter to accept() is
unchanged (not connected to the client) and
continues to listen for new connection requests.
On failure, accept() returns -1.
Server
socket()
bind()
listen()
accept()
(Block until connection)
recv()
send()
recv()
close()
30
Accepts Connection:
Illustration
pipe
Newly returned socket
accept
Server
Process
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.
Create a TCP socket
Establish connection
Communicate
Close the connection
2.
3.
4.
Bind socket to a port
Set socket to listen
Repeatedly:
a. Accept new connection
b. Communicate
c. Close the connection 34
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.
Create a TCP socket
Establish connection
Communicate
Close the connection
1.
2.
3.
4.
Create a TCP socket
Bind socket to a port
Set socket to listen
Repeatedly:
a. Accept new connection
b. Communicate
c. Close the connection 37
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.
Create a TCP socket
Establish connection
Communicate
Close the connection
2.
3.
4.
Bind socket to a port
Set socket to listen
Repeatedly:
a. Accept new connection
b. Communicate
c. Close the connection 39
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);
/* 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");
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
LSB is at the lowest address
MSB
Big-endian
byte order
16-bit value
Low-order byte
MSB is at the lowest address
Little-endians are Intel x86
and DEC Alpha architectures
Address A+1
LSB
High-order byte
Address A
Increasing memory address
Big-endians are Motorola
68000 family and Sparc
43
Implications of Byte Order
(1)
Unfortunately there is no standard between
these two byte orderings and we encounter
systems that use both formats.
We refer to the byte ordering used by a given
system as host byte order.
44
Implications of Byte Order
(2)
The sender and the receiver must agree
on the order in which the bytes of these
multi-byte field transmitted: specify
network byte order, which is big-endian
byte ordering.
44
Byte Order Functions
htons(), htonl(), ntohs(), ntohl()
Converts host to network byte order
and vice versa
#include <netinet/in.h>
short int htons(short int hostShort)
long int htonl(long int hostLong)
short int ntohs(short int netShort)
long int ntohl(long int netLong)
hostShort Short integer in host byte order
hostLong Long integer in host byte order
netShort Short integer in network byte order
netLong Long integer in network byte order
Short 16 bit integer, Long 32 bit integer
45
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
The function inet_addr( ) converts the
string representation of the servers Internet
address (expected in dotted-quad format)
into a 32-bit binary representation.
returns 32-bit binary network byte
ordered IPv4 address
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
TCP segment structure
50
TCP 3-way handshake:
segment exchange
Server Allocates the TCP
Buffers and variables to the
connection
Client allocates the
TCP buffers and
variables to the
connection
51
Closing a TCP connection
52
TCP states visited by
client TCP
TCP states visited by server-side
TCP
53
Socket structure
All data structures in the
socket layer and TCP
implementation that
contain state information
relevant to this socket
abstraction.
The socket structure
contains following:
Data structures associated with
a TCP Socket
Addresses
FIFO queues
Additional protocol state
information relevant to the
opening and closing TCP
handshakes (For a TCP socket)
54
Buffering and TCP (1)
No correspondence between send()s and
recv()s
rv = connect (s, .... ) ;
.
.
rv = send(s, buffer0, 1000,
0);
.
.
rv = send(s, buffer1, 2000,
0);
.
.
rv = send(s, buffer2, 5000,
0);
The way these 8000
bytes are grouped for
delivery at the
receiving end of the
connection depends on
The timing between the
calls to send() and recv()
at the two ends of the
connection
The size of the buffers
provided to the recv()
calls.
55
Buffering and TCP (2)
Three FIFO queues
SendQ: Bytes buffered in the sockets layer at
the sender that have not yet been successfully
transmitted to the receiving host.
RecvQ: Bytes buffered in the sockets layer at
the receiver waiting to be delivered to the
receiving program, that is, waiting to be
returned via recv().
Delivered: Bytes already returned to the
receiving program via recv().
56
Buffering and TCP (3)
Bytes to SendQ
SendQ to RecvQ
A call to send() appends bytes to SendQ.
The TCP protocol is responsible for moving bytes in
order from SendQ to RecvQ.
This transfer cannot be controlled or directly observed by
the user program and that it occurs in chunks whose
sizes are more or less independent of the size of the
buffers passed in send() calls.
RecvQ to Delivered
Bytes are moved from RecvQ to Delivered as a result of
recv() calls by the receiving program
The size of the transferred chunks depends on the
amount of data in RecvQ and the size of the buffer given
57
to recv().
Buffering and TCP (4)
State of the three queues after three calls to
send() but before any recv()s at the other end.
First transfer from SendQ to RecvQ 1500 bytes
58
Buffering and TCP (5)
After first recv()
recv() is called with buffer size of 2000 bytes
Second transfer from SendQ to RecvQ 6000
bytes
59
Buffering and TCP (6)
After another recv()
recv() is called with buffer size of 4000 bytes
The number of bytes returned by the next call to
recv() depends on
The size of the buffer
The timing with respect to the transfer of data from the
send-side queue to the receive-side queue.
60
Deadlock (1)
Buffers are finite and therefore, they can fill up.
RecvQ is full
TCP flow control mechanism kicks in and prevents the
transfer of any bytes from the sending hosts SendQ
until space becomes available in RecvQ (as a result of
call to recv()).
A sending program can continue to call send() until
SendQ is full.
SendQ is full
send() blocks until space becomes available, that is, until
some bytes are transferred to the receiving hosts
RecvQ.
If RecvQ is also full, everything stops until the receving
program calls recv(), so that some bytes can be
transferred to Delivered.
61
Deadlock (2)
SQS: SendQ size
and
RQS: RecvQ size
Assume default (blocking) semantics
A send() call with a size parameter n such that
n > SQS
Will not return until at least (n - SQS) bytes have been
transferred to RecvQ at the receving host.
If n exceeds (SQS + RQS),
send() can not return until after the receiving program has
called
recv() enough times or with a big enough buffer to allow at
least
[n-(SQS+RQS)] bytes of data to be delivered.
If the receiving program does not call recv(), a
62
Deadlock (3)
If both the ends of the connection call send()
simultaneously with size parameters >
(SQS+RQS), deadlock will result:
Neither send() will ever complete, and both
programs will remain blocked forever.
One situation if both programs are sending
simultaneously.
63
Deadlock (4)
Deadlock caused by simultaneous send()s.
SQS and RQS are 500 at both A and B
64
Deadlock (5)
Design the protocol carefully to avoid
simultaneous send()s in both directions
65
Performance Implications
Throughput
Throughput achievable over a TCP
connection is affected by
Rate at which bytes of user data from the
sender are made available to the receiving
program.
The sizes of the SendQ and RecvQ buffers
Bigger buffers generally result higher
throughput.
There is always a system-imposed
maximum size for each buffer.
66
TCP Socket Life Cycle
The sockets interface permits send() and
recv() on a TCP socket only when it is in
the connected or Established state, that
is, only when it has completed the opening
handshake exchange required to establish
a TCP connection.
How a socket gets to and from the
Established state?
67
TCP Socket Life Cycle
Connecting (1)
Client side connection
establishment
68
TCP Socket Life Cycle
Connecting (2)
Server side socket setup
69
TCP Socket Life Cycle
Connecting (3)
Incoming connection request
processing
70
TCP Socket Life Cycle
Connecting (4)
accept() processing
71
TCP Socket Life Cycle closing a
TCP connection (1)
Closing a TCP connection
first
72
TCP Socket Life Cycle
closing a TCP connection (2)
Closing after the other end closes
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)
recv() -> Hi Jane
recv() -> Hello
recv() -> Bob
send(Hi )
send(Jane)
74
Closing a Connection
close() used to delimit communication
Analogous to EOF
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
UDP performs only two functions:
1.It adds another layer of addressing (ports)
to that of IP
2.It detects data corruption that may occur in
transit and discards any corrupted
datagrams
UDP sockets preserve message boundaries.
UDP provides best-effort service
76
Characteristics of UDP
sockets
UDP sockets do not have to be connected
before being used.
TCP Telephone communication
UDP Communicating by Postal Mail
Specify destination address for each
datagram
On receiving side, UDP socket is a like a
mail-box into which letters of packages
from many different sources can be
placed.
77
UDP Client-Server
Server
socket()
bind()
Client
recvfrom()
socket()
(Block until receive datagram)
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)
The first four parameters to sendto() are the
same as those for send().
The two additional parameters specify the
message's destination.
Again, they will invariably be a pointer to a
struct sockaddr_in and sizeof(struct
sockaddr_in), respectively.
79
Functions (2)
int recvfrom(int socket, void *msg, unsigned int
msgLength,
int flags, struct sockaddr *srcAddr,
unsigned
int *addrLen)
recvfrom() takes the same parameters as recv()
but, in addition, has two parameters that inform
the caller of the source of the received
datagram.
addrLen is an in-out parameter in recvfrom():
On input it specifies the size of the address
buffer srcAddr;
On output it specifies the size of the address
that was
copied into the buffer.
80
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