Title: Lecture 17: Sockets
1Lecture 17 Sockets
- Prev. summary
- Sockets
- TCP client functions
Application
Transport
Network
Link
- Todays lecture
- TCP server functions
2Client/server socket interaction TCP
Server
Client
create socket, portx, for incoming request
welcomeSocket socket() bind(welcomeSocket,) list
en(welcomeSocket,..)
create socket, connect to hostid, portx
clientSocket socket() connect(clientSocket,
)
send request using socket send(clientSocket)
read request from socket recv(connectionSocket..)
write reply to socket send(connectionSocket)
read reply from socket recv(clientSocket,)
close close(connectionSocket)
close close(clientSocket)
3Bind Function
- Bind function is used to assign a local protocol
address to a socket - uses a socket descriptor (sockfd) created by the
socket function - uses protocol-specific address and its size
(myaddr, addrlen) -
include ltsys/socket.hgt int bind (int
sockfd, const struct sockaddr myaddr, socklen_t
addrlen) Returns 0 if OK,-1 if error
4Bind Function
-
- Servers bind their well-known ports when they
start - Normally, a TCP client does not bind a port
number. Why? - include ltsys/socket.hgt
- int bind (int sockfd, const struct sockaddr
myaddr, socklen_t addrlen) - Returns 0 if OK,-1 if error
5Bind Function
- binding IP address to a socket
- TCP server bind restricts the socket to receive
connections - destined only to that IP address (i.e., has
multiple IP addresses). - TCP client assigns source IP address for
sending datagrams
Result
Process specifies
IP address
Port
wildcard
0
kernel chooses IP address and port
wildcard
nonzero
kernel chooses IP address, process specifies port
0
local IP addr
process specifies IP address, kernel chooses port
nonzero
local IP addr
process specifies IP address and port
wildcard INADDR_ANY (IPv4)
6Allocation of Port Numbers
5001 65535
1 1023
1024 5000
BSD servers (nonprivilidged)
BSD reserved ports
BSD ephemeral (short lived) ports
49152 65535
1 1023
1024
49151
IANA dynamic or private
IANA registered ports
IANA well-known ports
IANA Internet Assigned Numbers Authority
7bind() Example
- int mysock,err
- struct sockaddr_in myaddr
- memset(myaddr, 0, sizeof(myaddr))
- mysock socket(PF_INET,SOCK_STREAM,IPPROTO_T
CP) - myaddr.sin_family AF_INET
- myaddr.sin_port htons( portnum )
- myaddr.sin_addr htonl( ipaddress)
- errbind(mysock, (sockaddr ) myaddr,
sizeof(myaddr)) - if (errlt0)
- HandleError
8Network Byte Order
- 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.
Common Mistake Ignoring Network Byte Order
9Byte Ordering
- Big-Endian machine the most significant byte has
the lowest address - Motorola 68000 and Sparc
- Little-Endian machine the least significant byte
has the lowest address - Intel x86 and DEC Alpha architectures
- Network byte order Big-Endian
10Network Byte Order Functions
- h host byte order n network byte
order - s short (16bit) l long
(32bit) - uint16_t htons(uint16_t)
- uint16_t ntohs(uint_16_t)
- uint32_t htonl(uint32_t)
- uint32_t ntohl(uint32_t)
11Byte ordering
- Whenever sending a multibyte, binary value from
one machine to another machine - Passing values to an API function in sockaddr
structure - myaddr.sin_port htons( portnum )
- myaddr.sin_addr htonl( ipaddress)
- Receiver needs to convert before using the values
12Client/server socket interaction TCP
Server
Client
create socket, portx, for incoming request
welcomeSocket socket() bind(welcomeSocket,) list
en(welcomeSocket,..)
create socket, connect to hostid, portx
clientSocket socket() connect(clientSocket,
)
send request using socket send(clientSocket)
read request from socket recv(connectionSocket..)
write reply to socket send(connectionSocket)
read reply from socket recv(clientSocket,)
close close(connectionSocket)
close close(clientSocket)
13 Listen Function
socket
active socket
passive socket
(default)
a socket used to wait for an incoming
connection
a socket used for initiating a
connection
- Listen function
- converts an unconnected socket into a passive
socket indicating that the kernel should accept
incoming connection requests to this socket (a
created socket is assumed to be active i.e., a
connect will follow) - is called only by a TCP server. Why?
14Listen Function
client
complete connection queue
TCP clients connection request
complete
server
TCP server will accept completed connection
incomplete connection queue
include ltsys/socket.hgt int listen (int
sockfd, int backlog) Returns 0 if OK,-1 if
error
- the second argument (backlog) specifies the
maximum number of connections the kernel should
queue for this socket -
-
15Accept Function
- Accept function returns the next completed
connection from the front of the completed
connection queue. - If the completed connection queue is empty,
process is put to sleep - if accept is succesful, it returns a new socket
descriptor (newsockfd) -
-
include ltsys/socket.hgt int accept (int sockfd,
const struct sockaddr cliaddr , socklen_t
addrlen) Returns nonnegative descriptor if
OK,-1 if error
16Socket Descriptor Data Structure
Descriptor Table
Family PF_INET Service SOCK_STREAM Local IP
111.22.3.4 Remote IP 123.45.6.78 Local Port
2249 Remote Port 3726
0
1
2
3
4
All fields are filled for socket descriptors
returned by the connect function.
17A simple TCP Server
/ Create socket for incoming connections /
if ((servSock socket(PF_INET, SOCK_STREAM,
IPPROTO_TCP)) lt 0) DieWithError("socket()
failed") / Construct local address
structure / memset(echoServAddr, 0,
sizeof(echoServAddr)) / Zero out 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(servSock, (struct
sockaddr ) echoServAddr, sizeof(echoServAddr))
lt 0) DieWithError("bind() failed")
/ Mark the socket so it will listen for incoming
connections / if (listen(servSock,
MAXPENDING) lt 0) DieWithError("listen()
failed")
18 for () / Run forever / / Set
the size of the in-out parameter /
clntLen sizeof(echoClntAddr) / Wait
for a client to connect / if ((clntSock
accept(servSock, (struct sockaddr )
echoClntAddr,
clntLen)) lt 0) DieWithError("accept()
failed") / clntSock is connected to a
client! / printf("Handling client
s\n", inet_ntoa(echoClntAddr.sin_addr))
HandleTCPClient(clntSock) / NOT
REACHED /
19Summary
communication end-point
communication end-point
socket
socket
client
server
- socket Create a descriptor
- connect Initiate message exchange for
connection - bind Set local IP address and port of the
socket - listen Place socket in passive mode, set queue
len - accept Accept the next incoming connection
(handshake completed) - close Terminate communication, deallocate
descriptor
20Metaphor for Good Relationships
- To succeed in relationships
- you need to establish your own identity.
- you need to be open accepting.
- you need to establish contacts.
- you need to take things as they come, not as you
expect them.
bind()
accept()
connect()
read might return 1 byte
21Sending Data Through A Socket
sendto
sendmsg
-
- int write (int sockfd, char buff , int
nbytes) - int send (int sockfd, const void buff , int
nbytes , int flag) - int sendto (int sockfd, void buff , int
nbytes , int flag , - struct sockaddr to , socklen_t addrlen)
- int sendmsg (int sockfd, struct msghdr msg,
int flag ) - Returns number of bytes written if OK,-1 if
error
send
Can specify the destination addr
write
only for connected sockets
22Receiving Data from a Socket
recvfrom
recvmsg
-
- int read (int sockfd, char buff , int
nbytes) - int recv (int sockfd, void buff , int
nbytes , int flag) - int recvfrom (int sockfd, void buff , int
nbytes , int flag , - struct sockaddr to , socklen_t addrlen)
- int recvmsg (int sockfd, struct msghdr msg,
int flag ) - Returns number of bytes read if OK,-1 if
error
recv
Can specify the destination addr
read
only for connected sockets
23Why Generic Socket Address?
Used to cast pointers to protocol specific
structures
For instance kernel takes callers pointer,
casts it to sockaddr and then looks at the
value of sa_family to determine the type of
the structure. include ltsys/socket.hgt struct
sockaddr uint8_t sa_len sa_family_t sa_famil
y / address family AF_xxx / char sa_data14
/ protocol specific address /
24Various Socket Address Structures
Datalink sockaddr_dl()
IPv6 sockaddr_in6()
IPv4 sockaddr_in()
Unix sockaddr_un()
length
AF_LINK
length
AF_INET
length
AF_INET6
length
AF_LOCAL
interface index
16-bit port
16-bit port
Pathname (up to 104 bytes)
type
name len
32-bit IPv4 address
32-bit flow label
addr len
sel len
(unused)
128-bit IPv6 address
interface name and link-layer address
variable length
fixed length (16-bytes)
fixed length (24-bytes)
variable length
25Socket API
-
- explicitly created, used, released by
applications
hostB
hostA
controlled by application developer
controlled by application developer
controlled by operating system
controlled by operating system
internet
server
client
26Necessary Background Information POSIX data
types
- int8_t signed 8bit int
- uint8_t unsigned 8 bit int
- int16_t signed 16 bit int
- uint16_t unsigned 16 bit int
- int32_t signed 32 bit int
- uint32_t unsigned 32 bit int
27More POSIX data types
- sa_family_t address family
- socklen_t length of struct
- in_addr_t IPv4 address
- in_port_t IP port number
28Generic socket addresses
- struct sockaddr
- unsigned short sa_family
- char sa_data14
-
- sa_family specifies the address type
- AF_INET (Internet protocol address family)
- sa_data specifies the address value.
29struct sockaddr_in (IPv4)
- struct sockaddr_in
- unsigned short sin_family
- unsigned short sin_port
- struct in_addr sin_addr
- char sin_zero8
-
- struct in_addr
- unsigned long s_addr
-
30Address
- sockaddr_in is another view of the data in
sockaddr structure. - Fill, cast, and pass to the socket functions
- Socket functions look at the sa_family
- PF_INET and AF_INET
- allow maximum flexibility, e.g., the same
protocol family can use different address
families.
31sockaddr_in
sockaddr
sa_family
sa_data