0% found this document useful (0 votes)
22 views

Notes

Uploaded by

dotel49126
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
22 views

Notes

Uploaded by

dotel49126
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 90

Lecture 2: Introduction to Unix

Network Programming

Reference: Stevens Unix


Network Programming

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 1


Internet Protocols

Application
FTP HTTP Video Audio
Layers

Transport TCP UDP

Network IP

Data Link
Ethernet WLAN 4G WiFi
Physical

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 2


Direction and Principles

Programming

learn to use Internet for


Transport communication (with focus
on implementation of
Network
networking concepts)
Data Link

Physical learn to build network from


ground up
Principles and
Concepts

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 3


Network Programming

n How should two hosts communicate with


each other over the Internet?
n The “Internet Protocol” (IP)
n Transport protocols: TCP, UDP

n How should programmers interact with the


protocols?
n Sockets API – application programming interface
n De facto standard for network programming

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 4


Network Programming with
Sockets

n Sockets API
¡ An interface to the transport layer
n Introduced in 1981 by BSD 4.1
n Implemented as library and/or system calls
n Similar interfaces to TCP and UDP
n Can also serve as interface to IP (for super-
user); known as “raw sockets”

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 5


How can many hosts
communicate?

n Multiplex traffic with routers


n Question: How to identify the destination?
n Question: How to share bandwidth across different flows?
Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 6
Identifying hosts with
Addresses and Names
n IP addresses
¡ Easily handled by routers/computers
¡ Fixed length
¡ E.g.: 128.121.146.100
n But how do you know the IP address?
¡ Internet domain names
¡ Human readable, variable length
¡ E.g.: twitter.com
n But how do you get the IP address from the domain
name?
¡ Domain Name System (DNS) maps between them
Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 7
How can many hosts share
network resources?
File 1

File 2

File 3

n Solution: divide traffic into “IP packets”


¡ At each router, the entire packet is received, stored, and
then forwarded to the next router

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 8


How can many hosts share
network resources?
File 1

File 2

File 3 header data

n Solution: divide traffic into “IP packets”


¡ Use packet “headers” to denote which connection the
packet belongs to
n Contains src/dst address/port, length, checksum, time-to-live,
protocol, flags, type-of-service, etc
Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 9
Is IP enough?
n What if host runs multiple applications?
¡ Use UDP: 16-bit “Port numbers” in header distinguishes
traffic from different applications
n Or if content gets corrupted?
¡ Use UDP: “Checksum” covering data, UDP header, and
IP header detects flipped bits
n User Datagram Protocol (UDP)
¡ Properties
n Unreliable - no guaranteed delivery
n Unordered - no guarantee of maintained order of delivery
n Unlimited Transmission - no flow control
¡ Unit of Transfer is “datagram” (a variable length packet)
Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 10
Is UDP enough?
n What if network gets congested? Or packets get
lost/reordered/duplicated?
n UseTransport Control Protocol (TCP)
¡ Guarantees reliability, ordering, and integrity
¡ Backs off when there is congestion
¡ Connection-oriented (Set up connection before
communicating, Tear down connection when done)
¡ Gives ‘byte-stream” abstraction to application
¡ Also has ports, but different namespace from UDP
n Which one is better, TCP or UDP?
n Why not other hybrid design points?
Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 11
How should we program
networked apps?

n How can we compose together


programs running on different
machines?
¡ Client-server model

n What sort of interfaces should we


reveal to the programmer?
¡ Sockets API
Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 12
Client-Server Model
n A client initiates a request to a well-known server
n Example: the web
GET index.html
(request for web page)

HTTP/1.0 200 OK…


Client (response, including web page) Web server

n Other examples: FTP, SSH/Telnet, SMTP (email),


Print servers, File servers

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 13


Client-Server Model
n Asymmetric
Communication
¡ Client sends requests
Client
¡ Server sends replies
n Server/Daemon
Client
¡ Well-known name and
Server port
¡ Waits for contact
Client
¡ Processes requests,
sends replies

Client
n Client
Can you think of any network ¡ Initiates contact
apps that are not client/server? ¡ Waits for response
Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 14
Server-side service models

n Concurrent
¡ Server processes multiple clients’ requests
simultaneously
n Sequential
¡ Server processes only one client’s requests at a
time
n Hybrid
¡ Server maintains multiple connections, but
processes responses sequentially
n Which one is best?
Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 15
Wanna See Real Clients and
Servers?
n Apache Web server
¡ Open source server first released in 1995
¡ Name derives from “a patchy server” ;-)
¡ Software available online at http://www.apache.org
n Mozilla Web browser
¡ http://www.mozilla.org/developer/
n Sendmail
¡ http://www.sendmail.org/
n BIND Domain Name System
¡ Client resolver and DNS server
¡ http://www.isc.org/index.pl?/sw/bind/
Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 16
What interfaces to expose to
programmer?

n Stream vs. Datagram sockets


n Stream sockets
¡ Abstraction: send a long stream of
characters
¡ Typically implemented on top of TCP
n Datagram sockets
¡ Abstraction: send a single packet
¡ Typically implemented on top of UDP
Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 17
Stream sockets
This is a long sequence of
send( This is a long
text I would like to send to
sequence of text I would like
the other host =recv(socket)
to send to the other host )

Sockets API Sockets API

This is a long
sequence of text
I would like to send
to the other host

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 18


Datagram sockets
sendto( This is a long ) This is a long =recvfrom(socket)
sendto( sequence of text )
sequence of text =recvfrom(socket)
sendto( I would like to
I would like to send =recvfrom(socket)
send ) sendto( to the other
to the other host =recvfrom(socket)
host )

Sockets API Sockets API

This is a long
sequence of text
I would like to send
to the other host

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 19


What specific functions to
expose?

n Data structures to store information about


connections and hosts

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 20


Socket Address Structure
n IP address:
struct in_addr {
in_addr_t s_addr; /* 32-bit IP address */
};

n TCP or UDP address:


struct sockaddr_in {
short sin_family; /* e.g., AF_INET */
ushort sin_port; /* TCP/UDP port */
struct in_addr; /* IP address */
};

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 21


Structure: addrinfo
n The addrinfo data structure (from
/usr/include/netdb.h)
¡ Canonical domain name and aliases
¡ List of addresses associated with machine
¡ Also address type and length information

int ai_flags Input flags


int ai_family Address family of socket
int ai_socktype Socket type
int ai_protocol Protocol of socket
socklen_t ai_addrlen Length of socket address
struct sockaddr *ai_addr Socket address of socket
char *ai_canonname Canonical name of service location
struct addrinfo *ai_next Pointer to next in list

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 22


Address Access/Conversion
Functions
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
int getaddrinfo(const char *restrict node,
const char *restrict service,
const struct addrinfo *restrict hints,
struct addrinfo **restrict res);
n Parameters
¡ node: host name or IP address to connect to
¡ service: a port number (“80“) or the name of a service
(found /etc/services: “http”)
¡ hints: a filled out struct addrinfo

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 23


Example: Server
int status;
struct addrinfo hints;
struct addrinfo *servinfo; // point to the results

memset(&hints, 0, sizeof hints); // empty struct


hints.ai_family = AF_UNSPEC; // IPv4 or IPv6
hints.ai_socktype = SOCK_STREAM; // TCP stream sockets
hints.ai_flags = AI_PASSIVE; // fill in my IP for me

if ((status = getaddrinfo(NULL, "3490", &hints, &servinfo)) != 0) {


fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
exit(1);
}
// servinfo now points to a linked list of 1 or more struct addrinfos
// ... do everything until you don't need servinfo anymore ....

freeaddrinfo(servinfo); // free the linked-list

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 24


Example: getaddrinfo
int status;
struct addrinfo hints;
struct addrinfo *servinfo; // pointer to results

memset(&hints, 0, sizeof hints); // empty struct


hints.ai_family = AF_UNSPEC; // don't care IPv4/IPv6
hints.ai_socktype = SOCK_STREAM; // TCP stream sockets

// get ready to connect


status = getaddrinfo("www.example.net", "3490", &hints,
&servinfo);

// servinfo now points to a linked list of 1 or more struct


addrinfos

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 25


What specific functions to
expose?

n Data structures to store information about


connections and hosts
n Functions to create a socket

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 26


Function: socket
int socket (int family, int type, int
protocol);
n Create a socket.
¡ Returns file descriptor or -1. Also sets errno on failure.
¡ family: address family (namespace)
n AF_INET for IPv4
n other possibilities: AF_INET6 (IPv6), AF_UNIX or AF_LOCAL
(Unix socket), AF_ROUTE (routing)
¡ type: style of communication
n SOCK_STREAM for TCP (with AF_INET)
n SOCK_DGRAM for UDP (with AF_INET)
¡ protocol: protocol within family
n typically 0

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 27


Example: socket
int sockfd, new_fd; /* listen on sock_fd, new
connection on new_fd */
struct sockaddr_in my_addr; /* my address */
struct sockaddr_in their_addr; /* connector addr */
int sin_size;

if ((sockfd = socket(AF_INET, SOCK_STREAM, 0))==-1){


perror("socket");
exit(1);
}

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 28


What specific functions to
expose?

n Data structures to store information about


connections and hosts
n Functions to create a socket
n Functions to establish connections

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 29


TCP Connection Setup
client server
socket
socket bind
connect listen

connection moved
to complete queue

connect completes

connection added to
incomplete queue
accept

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 30


Function: bind
int bind (int sockfd, struct sockaddr*
myaddr, int addrlen);
n Bind a socket to a local IP address and port number
¡ Returns 0 on success, -1 and sets errno on failure
¡ sockfd: socket file descriptor (returned from socket)
¡ myaddr: includes IP address and port number
n IP address: set by kernel if value passed is INADDR_ANY,
else set by caller
n port number: set by kernel if value passed is 0, else set by
caller
¡ addrlen: length of address structure
n = sizeof (struct sockaddr_in)

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 31


TCP and UDP Ports
n Allocated and assigned by the Internet Assigned
Numbers Authority
¡ see RFC 1700 (for historical purposes only)

1-512 n standard services (see /etc/services)


n super-user only
513-1023 n registered and controlled, also used for identity
verification
n super-user only

1024-49151 n registered services/ephemeral ports

49152-65535 n private/ephemeral ports

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 32


Reserved Ports
Keyword Decimal Description Keyword Decimal Description
------- ------- ----------- ------- ------- -----------
0/tcp Reserved time 37/tcp Time
0/udp Reserved time 37/udp Time
tcpmux 1/tcp TCP Port Service name 42/tcp Host Name Server
tcpmux 1/udp TCP Port Service name 42/udp Host Name Server
echo 7/tcp Echo nameserver 42/tcp Host Name Server
echo 7/udp Echo nameserver 42/udp Host Name Server
systat 11/tcp Active Users nicname 43/tcp Who Is
systat 11/udp Active Users nicname 43/udp Who Is
daytime 13/tcp Daytime (RFC 867) domain 53/tcp Domain Name Server
daytime 13/udp Daytime (RFC 867) domain 53/udp Domain Name Server
qotd 17/tcp Quote of the Day whois++ 63/tcp whois++
qotd 17/udp Quote of the Day whois++ 63/udp whois++
chargen 19/tcp Character Generator gopher 70/tcp Gopher
chargen 19/udp Character Generator gopher 70/udp Gopher
ftp-data 20/tcp File Transfer Data finger 79/tcp Finger
ftp-data 20/udp File Transfer Data finger 79/udp Finger
ftp 21/tcp File Transfer Ctl http 80/tcp World Wide Web HTTP
ftp 21/udp File Transfer Ctl http 80/udp World Wide Web HTTP
ssh 22/tcp SSH Remote Login www 80/tcp World Wide Web HTTP
ssh 22/udp SSH Remote Login www 80/udp World Wide Web HTTP
telnet 23/tcp Telnet www-http 80/tcp World Wide Web HTTP
telnet 23/udp Telnet www-http 80/udp World Wide Web HTTP
smtp 25/tcp Simple Mail Transfer kerberos 88/tcp Kerberos
smtp 25/udp Simple Mail Transfer kerberos 88/udp Kerberos

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 33


Function: listen
int listen (int sockfd, int backlog);
n Put socket into passive state (wait for connections
rather than initiate a connection)
¡ Returns 0 on success, -1 and sets errno on failure
¡ sockfd: socket file descriptor (returned from socket)
¡ backlog: bound on length of unaccepted connection
queue (connection backlog); kernel will cap, thus better to
set high
¡ Example:
if (listen(sockfd, BACKLOG) == -1) {
perror("listen");
exit(1);
}
Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 34
Functions: accept
int accept (int sockfd, struct sockaddr* cliaddr,
int* addrlen);
n Block waiting for a new connection
¡ Returns file descriptor or -1 and sets errno on failure
¡ sockfd: socket file descriptor (returned from socket)
¡ cliaddr: IP address and port number of client (returned from
call)
¡ addrlen: length of address structure = pointer to int set to
sizeof (struct sockaddr_in)

n addrlen is a value-result argument


¡ the caller passes the size of the address structure, the kernel
returns the size of the client’s address (the number of bytes
written)

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 35


Functions: accept
sin_size = sizeof(struct sockaddr_in);
if ((new_fd = accept(sockfd, (struct sockaddr*)
&their_addr, &sin_size)) == -1) {
perror("accept");
continue;
}

n How does the server know which client it is?


¡ their_addr.sin_addr contains the client’s IP address
¡ their_addr.port contains the client’s port number

printf("server: got connection from %s\n",


inet_ntoa(their_addr.sin_addr));

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 36


Functions: accept

n Notes
¡ After accept() returns a new socket
descriptor, I/O can be done using read() and
write()
¡ Why does accept() need to return a new
descriptor?

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 37


Example: Server
my_addr.sin_family = AF_INET; /* host byte order */
my_addr.sin_port = htons(MYPORT); /* short, network
byte order */
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
/* automatically fill with my IP */
bzero(&(my_addr.sin_zero), 8); /* zero struct */

if (bind(sockfd, (struct sockaddr *)&my_addr,


sizeof(struct sockaddr)) == -1) {
perror("bind");
exit(1);
}

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 38


Example: Server
if (listen(sockfd, BACKLOG) == -1) {
perror("listen");
exit(1);
}

while(1) { /* main accept() loop */


sin_size = sizeof(struct sockaddr_in);
if ((new_fd = accept(sockfd, (struct sockaddr*)
&their_addr,&sin_size)) == -1) {
perror("accept");
continue;
}
printf("server: got connection from %s\n",
inet_ntoa(their_addr.sin_addr));

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 39


Function: connect
int connect (int sockfd, struct
sockaddr* servaddr, int addrlen);
n Connect to another socket.
¡ Returns 0 on success, -1 and sets errno on failure
¡ sockfd: socket file descriptor (returned from socket)
¡ servaddr: IP address and port number of server
¡ addrlen: length of address structure
n = sizeof (struct sockaddr_in)
n Can use with UDP to restrict incoming datagrams
and to obtain asynchronous errors

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 40


Example: Client
their_addr.sin_family = AF_INET; /* interp’d by host */
their_addr.sin_port = htons (PORT);
their_addr.sin_addr = *((struct in_addr*)he->h_addr);
bzero (&(their_addr.sin_zero), 8);
/* zero rest of struct */
if (connect (sockfd, (struct sockaddr*)&their_addr,
sizeof (struct sockaddr)) == -1) {
perror (“connect”);
exit (1);
}

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 41


What specific functions to
expose?

n Data structures to store information about


connections and hosts
n Functions to create a socket
n Functions to establish connections
n Functions to send and receive data

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 42


TCP Connection Example
client server
socket
socket bind
connect listen

write accept
read
write
read

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 43


Functions: write
int write (int sockfd, char* buf, size_t nbytes);
n Write data to a stream (TCP) or “connected”
datagram (UDP) socket
¡ Returns number of bytes written or -1 and sets errno on
failure
¡ sockfd: socket file descriptor (returned from socket)
¡ buf: data buffer
¡ nbytes: number of bytes to try to write
¡ Example:

if((w = write(fd, buf, sizeof(buf))) < 0) {


perror(“write”);
exit(1);
}

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 44


Functions: write
int write (int sockfd, char* buf, size_t nbytes);
n Notes
¡ write blocks waiting for data from the client
¡ write may not write all bytes asked for
n Does not guarantee that sizeof(buf) is written
n This is not an error
n Simply continue writing to the device
¡ Some reasons for failure or partial writes
n Process received interrupt or signal
n Kernel resources unavailable (e.g., buffers)

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 45


Example: writen
/* Write "n" bytes to a descriptor */
ssize_t writen(int fd, const void *ptr, size_t n) {
size_t nleft;
ssize_t nwritten;
nleft = n;
while (nleft > 0) {
if ((nwritten = write(fd, ptr, nleft)) < 0) {
write returned if (nleft == n)
a potential error return(-1); /* error, return -1 */
else
break; /* error, return amount written so far */
}
0 bytes were else
if (nwritten == 0)
written break;
Update number nleft -= nwritten;
ptr += nwritten;
of bytes left to }
write and return(n - nleft); /* return >= 0 */
pointer into }
buffer
Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 46
Functions: send
int send(int sockfd, const void * buf, size_t
nbytes, int flags);
n Send data un a stream (TCP) or “connected”
datagram (UDP) socket
¡ Returns number of bytes written or -1 and sets errno on
failure
¡ sockfd: socket file descriptor (returned from socket)
¡ buf: data buffer
¡ nbytes: number of bytes to try to write
¡ flags: control flags
n MSG_PEEK: get data from the beginning of the receive queue
without removing that data from the queue

n Example
len = strlen(msg);
bytes_sent = send(sockfd, msg, len, 0);
Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 47
Functions: read
int read (int sockfd, char* buf, size_t nbytes);
n Read data from a stream (TCP) or “connected”
datagram (UDP) socket
¡ Returns number of bytes read or -1, sets errno on failure
¡ Returns 0 if socket closed
¡ sockfd: socket file descriptor (returned from socket)
¡ buf: data buffer
¡ nbytes: number of bytes to try to read
¡ Example
if((r = read(newfd, buf, sizeof(buf))) < 0) {
perror(“read”); exit(1);
}

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 48


Functions: read
int read (int sockfd, char* buf, size_t nbytes);
n Notes
¡ read blocks waiting for data from the client
¡ read may return less than asked for
n Does not guarantee that sizeof(buf) is read
n This is not an error
n Simply continue reading from the device

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 49


Example: readn
/* Read "n" bytes from a descriptor */
ssize_t readn(int fd, void *ptr, size_t n) {
size_t nleft;
ssize_t nread;
nleft = n;
while (nleft > 0) {
if ((nread = read(fd, ptr, nleft)) < 0) {
read returned
if (nleft == n)
a potential error return(-1); /* error, return -1 */
else
break; /* error, return amt read */
0 bytes were }
read else
if (nread == 0)
Update number break; /* EOF */
of bytes left to nleft -= nread;
read and ptr += nread;
pointer into }
return(n - nleft); /* return >= 0 */
buffer
Spring 2018} Copyright ©: CS 438 Staff, University of Illinois 50
Functions: recv
int recv(int sockfd, void *buf, size_t nbytes,
int flags);
n Read data from a stream (TCP) or “connected”
datagram (UDP) socket
¡ Returns number of bytes read or -1, sets errno on failure
¡ Returns 0 if socket closed
¡ sockfd: socket file descriptor (returned from socket)
¡ buf: data buffer
¡ nbytes: number of bytes to try to read
¡ flags: see man page for details; typically use 0

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 51


Functions: recv
int read (int sockfd, char* buf, size_t nbytes);
n Notes
¡ read blocks waiting for data from the client but does not
guarantee that sizeof(buf) is read
¡ Example
if((r = read(newfd, buf, sizeof(buf))) < 0) {
perror(“read”); exit(1);
}

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 52


Sending and Receiving Data

n Datagram sockets aren't connected to a


remote host
¡ What piece of information do we need to give
before we send a packet?
¡ The destination/source address!

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 53


UDP Connection Example
client server

socket
socket bind
sendto

recvfrom
sendto

recvfrom

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 54


Functions: sendto
int sendto (int sockfd, char* buf, size_t nbytes,
int flags, struct sockaddr* destaddr, int
addrlen);
n Send a datagram to another UDP socket
¡ Returns number of bytes written or -1 and sets errno on failure
¡ sockfd: socket file descriptor (returned from socket)
¡ buf: data buffer
¡ nbytes: number of bytes to try to read
¡ flags: see man page for details; typically use 0
¡ destaddr: IP address and port number of destination socket
¡ addrlen: length of address structure
n = sizeof (struct sockaddr_in)

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 55


Functions: sendto
int sendto (int sockfd, char* buf, size_t nbytes,
int flags, struct sockaddr* destaddr, int
addrlen);
n Example
n = sendto(sock, buf, sizeof(buf), 0,(struct
sockaddr *) &from,fromlen);
if (n < 0)
perror("sendto");
exit(1);
}

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 56


Functions: recvfrom
int recvfrom (int sockfd, char* buf, size_t
nbytes, int flags, struct sockaddr* srcaddr,
int* addrlen);
n Read a datagram from a UDP socket.
¡ Returns number of bytes read (0 is valid) or -1 and sets errno
on failure
¡ sockfd: socket file descriptor (returned from socket)
¡ buf: data buffer
¡ nbytes: number of bytes to try to read
¡ flags: see man page for details; typically use 0
¡ srcaddr: IP address and port number of sending socket
(returned from call)
¡ addrlen: length of address structure = pointer to int set to
sizeof (struct sockaddr_in)

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 57


Functions: recvfrom
int recvfrom (int sockfd, char* buf, size_t
nbytes, int flags, struct sockaddr* srcaddr,
int* addrlen);
n Example
n = recvfrom(sock, buf, 1024, 0, (struct sockaddr
*)&from,&fromlen);
if (n < 0) {
perror("recvfrom");
exit(1);
}

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 58


What specific functions to
expose?

n Data structures to store information about


connections and hosts
n Functions to create a socket
n Functions to establish connections
n Functions to send and receive data
n Functions to teardown connections

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 59


Functions: close
int close (int sockfd);
n Close a socket
¡ Returns 0 on success, -1 and sets errno on failure
¡ sockfd: socket file descriptor (returned from socket)

n Closes communication on socket in both directions


¡ All data sent before close are delivered to other side
(although this aspect can be overridden)
n After close, sockfd is not valid for reading or
writing

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 60


Functions: shutdown
int shutdown (int sockfd, int howto);
n Force termination of communication across a socket in one or
both directions
¡ Returns 0 on success, -1 and sets errno on failure
¡ sockfd: socket file descriptor (returned from socket)
¡ howto:
n SHUT_RD to stop reading
n SHUT_WR to stop writing
n SHUT_RDWR to stop both

n shutdown overrides the usual rules regarding duplicated


sockets, in which TCP teardown does not occur until all copies
have closed the socket

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 61


Note on close vs. shutdown
n close(): closes the socket but the connection is
still open for processes that shares this socket
¡ The connection stays opened both for read and write
n shutdown(): breaks the connection for all
processes sharing the socket
¡ A read will detect EOF, and a write will receive SIGPIPE
¡ shutdown() has a second argument how to close the
connection:
n 0 means to disable further reading
n 1 to disable writing
n 2 disables both

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 62


One tricky issue…

n Different processor architectures store


data in different “byte orderings”
¡ What is 200 in binary?
¡ 1100 1001?
or
¡ 1001 1100?

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 63


One tricky issue…
Where did the term
n Big Endian vs. Little Endian“endian” come from?
¡ Little Endian (Intel, DEC):
n Least significant byte of word is stored in the lowest
memory address
¡ Big Endian (Sun, SGI, HP, PowerPC):
n Most significant byte of word is stored in the lowest
memory address
¡ Example: 128.2.194.95
Big Endian 128 2 194 95

Little Endian 95 194 2 128


Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 64
One tricky issue…

n Big Endian vs. Little Endian: which should


we use for networked communication?
¡ Network Byte Order = Big Endian
n Allows both sides to communicate
n Must be used for some data (i.e. IP Addresses)
¡ What about ordering within bytes?
n Most modern processors agree on ordering within
bytes

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 65


Converting byte orderings

Solution: use byte ordering functions to convert.


int m, n;
short int s,t;

m = ntohl (n) net-to-host long (32-bit) translation


s = ntohs (t) net-to-host short (16-bit) translation
n = htonl (m) host-to-net long (32-bit) translation
t = htons (s) host-to-net short (16-bit) translation

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 66


Why Can’t Sockets Hide
These Details?
n Dealing with endian differences is tedious
¡ Couldn’t the socket implementation deal with this
¡ … by swapping the bytes as needed?
n No, swapping depends on the data type
¡ Two-byte short int: (byte 1, byte 0) vs. (byte 0, byte 1)
¡ Four-byte long int: (byte 3, byte 2, byte 1, byte 0) vs. (byte
0, byte 1, byte 2, byte 3)
¡ String of one-byte charters: (char 0, char 1, char 2, …) in
both cases
n Socket layer doesn’t know the data types
¡ Sees the data as simply a buffer pointer and a length
¡ Doesn’t have enough information to do the swapping
Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 67
Advanced Sockets: signal

n Problem: Socket at other end is closed


¡ Write to your end generates SIGPIPE
This signal kills the program by default!
¡

signal (SIGPIPE, SIG_IGN);


¡ Call at start of main in server
¡ Allows you to ignore broken pipe signals
¡ Can ignore or install a proper signal handler
¡ Default handler exits (terminates process)

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 68


Advanced Sockets

n Problem: How come I get "address already


in use" from bind()?
¡ You have stopped your server, and then re-
started it right away
¡ The sockets that were used by the first
incarnation of the server are still active

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 69


Advanced Sockets:
setsockopt
int yes = 1;
setsockopt (fd, SOL_SOCKET,
SO_REUSEADDR, (char *) &yes, sizeof
(yes));
¡ Call just before bind()

¡ Allows bind to succeed despite the existence of


existing connections in the requested TCP port
¡ Connections in limbo (e.g. lost final ACK) will
cause bind to fail

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 70


How to handle concurrency?
n Process requests serially
¡ Slow – what if you’re processing another request? What if
you’re blocked on read()?

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 71


A UDP Server

n How can a UDP


UDP Server server service
Port 3000 Port 2000 multiple ports
simultaneously?
UDP

IP

Ethernet Adapter

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 72


UDP Server: Servicing Two
Ports
int s1; /* socket descriptor 1 */
int s2; /* socket descriptor 2 */

/* 1) create socket s1 */
/* 2) create socket s2 */ What problems does
/* 3) bind s1 to port 2000 */
/* 4) bind s2 to port 3000 */
this code have?

while(1) {
recvfrom(s1, buf, sizeof(buf), ...);
/* process buf */
recvfrom(s2, buf, sizeof(buf), ...);
/* process buf */
}

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 73


How to handle concurrency?
n Process requests serially
¡ Slow – what if you’re processing another request? What if
you’re blocked on accept()?
n Multiple threads/processes (e.g. Apache, Chrome)
¡ Each thread/process handles one request
¡ fork(), pthreads
n Synchronous I/O (e.g. Squid web proxy cache)
¡ Maintain a “set” of file descriptors, whenever one has an
“event”, process it and put it back onto the set
¡ select(), poll()

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 74


Select
int select (int num_fds, fd_set* read_set, fd_set*
write_set, fd_set* except_set, struct timeval*
timeout);
n Wait for readable/writable file descriptors.
n Return:
¡ Number of descriptors ready
¡ -1 on error, sets errno
n Parameters:
¡ num_fds:
n number of file descriptors to check, numbered from 0
¡ read_set, write_set, except_set:
n Sets (bit vectors) of file descriptors to check for the specific condition
¡ timeout:
n Time to wait for a descriptor to become ready

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 75


File Descriptor Sets
int select (int num_fds, fd_set* read_set,
fd_set* write_set, fd_set* except_set, struct
timeval* timeout);

n Bit vectors
¡ Only first num_fds checked
¡ Macros to create and check sets

fds_set myset;
void FD_ZERO (&myset); /* clear all bits */
void FD_SET (n, &myset); /* set bits n to 1 */
void FD_CLEAR (n, &myset); /* clear bit n */
int FD_ISSET (n, &myset); /* is bit n set? */

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 76


File Descriptor Sets

n Three conditions to check for


¡ Readable:
n Data available for reading
¡ Writable:
n Buffer space available for writing
¡ Exception:
n Out-of-band data available (TCP)

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 77


Building Timeouts with Select
and Poll

n Time structure
Number of seconds since
midnight, January 1, 1970
GMT
struct timeval {
long tv_sec; /* seconds */
long tv_usec; /* microseconds */
};
unix will have its own "Y2K" problem one
second after 10:14:07pm, Monday
January 18, 2038 (will appear to be
3:45:52pm, Friday December 13, 1901)
Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 78
Select
Which file
n High-resolution sleep function descriptors are set
¡ All descriptor sets NULL and what should the
¡ Positive timeout
timeout value be?
n Wait until descriptor(s) become ready
¡ At least one descriptor in set
¡ timeout NULL
n Wait until descriptor(s) become ready or timeout occurs
¡ At least one descriptor in set
¡ Positive timeout
n Check descriptors immediately (poll)
¡ At least one descriptor in set
¡ 0 timeout

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 79


Select: Example
fd_set my_read;
FD_ZERO(&my_read);
FD_SET(0, &my_read);

if (select(1, &my_read, NULL, NULL) == 1) {


assert(FD_ISSET(0, &my_read);
/* data ready on stdin */
} What went wrong:
after select indicates
data available on a
connection, read
returns no data?

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 80


Select: Timeout Example
I nt main(void) {
struct timeval tv; Wait 2.5 seconds for
fd_set readfds; something to appear
tv.tv_sec = 2; on standard input
tv.tv_usec = 500000;
FD_ZERO(&readfds);
FD_SET(STDIN, &readfds);
// don't care about writefds and exceptfds:
select(1, &readfds, NULL, NULL, &tv);
if (FD_ISSET(STDIN, &readfds))
printf("A key was pressed!\n");
else
printf("Timed out.\n");
return 0;
}
Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 81
select() vs. poll()

Which to use?
n BSD-family (e.g., FreeBSD, MacOS)
¡ poll() just calls select() internally
n System V family (e.g., AT&T Unix)
¡ select() just calls poll() internally

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 82


Concurrent programming with
Posix Threads (pthreads)

n Thread management
¡ Creating, detaching, joining, etc.
Set/query thread attributes
n Mutexes
¡ Synchronization
n Condition variables
¡ Communications between threads that
share a mutex
Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 83
Creating a Thread
int pthread_create (pthread_t* tid,
pthread_attr_t* attr, void*(child_main), void*
arg);
n pthread_create() takes a pointer to a function as
one of its arguments
¡ child_main is called with the argument specified by arg
¡ child_main can only have one parameter of type void *
¡ Complex parameters can be passed by creating a structure
and passing the address of the structure
¡ The structure can't be a local variable

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 84


Example: pthreads
#include <pthread.h> void *PrintHello(void *threadid) {
#define NUM_THREADS 5 printf("\n%d: Hello World!\n", threadid);
pthread_exit(NULL);
}

int main (int argc, char *argv[]) {


pthread_t threads[NUM_THREADS];
int rc, t;

for(t=0;t < NUM_THREADS;t++) {


printf("Creating thread %d\n", t);
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
if (rc) {
printf("ERROR; pthread_create() return code is %d\n", rc);
exit(-1);
}
}
pthread_exit(NULL);
}

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 85


Example: pthread_join()
#include <pthread.h> /* Initialize and set thread detached
#include <stdio.h> attribute */
#include <stdlib.h> pthread_attr_init(&attr);
#define NUM_THREADS 4 pthread_attr_setdetachstate(&attr,
PTHREAD_CREATE_JOINABLE);
int main (int argc, char *argv[]) {
pthread_t thread[NUM_THREADS]; for(t=0; t<NUM_THREADS; t++) {
pthread_attr_t attr; printf("Main: creating thread %ld\n", t);
int rc; rc = pthread_create(&thread[t], &attr,
long t; BusyWork, (void *)t);
void *status; if (rc) {
printf("ERROR; return code is %d\n",
rc);
exit(-1);
}
}
/* Free attributes */
pthread_attr_destroy(&attr);

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 86


Example: pthread_join()
void *BusyWork(void *t) { int main (int argc, char *argv[]) {
int i; ...
long tid;
double result = 0.0; /* Wait for the other threads */
tid = (long)t; for(t=0; t<NUM_THREADS; t++) {
printf("Thread %ld starting...\n", rc = pthread_join(thread[t], &status);
tid); if (rc) {
for (i=0; i<1000000; i++) { printf("ERROR; return code is %d\n", rc);
result = result + sin(i) * tan(i); exit(-1);
} }
printf("Thread %ld result = %e\n", printf("Main: status for thread %ld: %ld\n",
tid, result); t, (long)status);
pthread_exit((void*) t); }
}
printf("Main: program completed. Exiting.\n");
pthread_exit(NULL);
}

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 87


Using pthreads

n When coding
¡ Include <pthread.h> first in all source
files
n When compiling
¡ Use compiler flag –D_REENTRANT
n When linking
¡ Link library -lpthread

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 88


pthread Error Handling
n pthreads functions do not follow the usual
Unix conventions
¡ Similarity
n Returns 0 on success
¡ Differences
n Returns error code on failure
n Does not set errno
¡ What about errno?
n Each thread has its own
n Define _REENTRANT (-D_REENTRANT switch to
compiler) when using pthreads

Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 89


Summary

n Unix Network Programming


¡ Transport protocols
n TCP, UDP
¡ Network programming
n Sockets API, pthreads
n Next
¡ Probability refresher
¡ Direct link networks
Spring 2018 Copyright ©: CS 438 Staff, University of Illinois 90

You might also like