Title: TDC561 Network Programming
1TDC561 Network Programming
- Week 5
- Client/Server Programming Aspects
- Client side Identifying the Server
Specifying a local IP
address TCP client design, UDP client design. - Server Side Daemon, inetd.
- Socket Options ( discussion will continue in a
next lecture )
- Camelia Zlatea, PhD
- Email czlatea_at_cs.depaul.edu
2References
- Douglas Comer, David Stevens, Internetworking
with TCP/IP Client-Server Programming, Volume
III (BSD Unix and ANSI C), 2nd edition, 1996
(ISBN 0-13-260969-X) - Chap. 6, 14 (partial)
- W. Richard Stevens, Network Programming
Networking API Sockets and XTI, Volume 1, 2nd
edition, 1998 (ISBN 0-13-490012-X) - Chap. 7,11,12, 21,22
3Aspects of Client/Server Programming
- Client-side aspects
- Identifying the Server.
- Looking up an IP address.
- Looking up a well known port name.
- Specifying a local IP address.
- TCP client design.
- UDP client design.
- Server-side aspects
- daemons
- inetd
4Identifying the Server
- Need an IP address, protocol and port.
- often use host names instead of IP addresses.
- usually the protocol (UDP vs. TCP) is not
specified by the user. - often the port is not specified by the user.
- Options
- hard-coded into the client program.
- require that the user identify the server.
- read from a configuration file.
- use a separate network service to lookup the
identity of the server.
5Byte Ordering
- Different computer architectures use different
byte ordering to represent/store multi-byte
values (such as 16-bit/32-bit integers) - 16 bit integer
Little-Endian (Intel)
Big-Endian (RISC-Sparc)
Low Byte
High Byte
Address A
High Byte
Low Byte
Address A1
6Byte Order and Networking
- Suppose a Big Endian machine sends a 16 bit
integer with the value 2 - A Little Endian machine will understand the
number as 512 - How do two machines with different byte-orders
communicate? - Using network byte-order
- Network byte-order big-endian order
0000000000000010
0000001000000000
7Network Byte Order
- Conversion of application-level data is left up
to the presentation layer. - Lower level layers communicate using a fixed byte
order called network byte order for all control
data. - TCP/IP mandates that big-endian byte ordering be
used for transmitting protocol information - All values stored in a sockaddr_in must be in
network byte order. - sin_port a TCP/IP port number.
- sin_addr an IP address.
8Network Byte Order Functions
- Several functions are provided to allow
conversion between host and network byte
ordering, - Conversion macros (ltnetinet/in.hgt)
- to translate 32-bit numbers (i.e. IP addresses)
- unsigned long htonl(unsigned long hostlong)
- unsigned long ntohl(unsigned long netlong)
- to translate 16-bit numbers (i.e. Port numbers)
- unsigned short htons(unsigned short hostshort)
- unsigned short ntohs(unsigned short netshort)
9Services and Ports
- Identifying of the server
- Many services are available via well known
addresses (names). - There is a mapping of service names to port
numbers - struct servent getservbyname(
- char service, char protocol )
- servent-gts_port
- is the port number in network byte order.
- Specifying a Local Address
- When a client creates and binds a socket it must
specify a local port and an IP address. - A client ask the kernel to assign the local IP
address - haddr-gtsin_addr.s_addr htonl(INADDR_ANY)
- Typically a randomly port available is assigned
with haddr-gtport htons(0)
10Example Identifying the Server
- Option read from a configuration file.
- / Initialize the server structure /
- server.sin_addr.s_addr INADDR_ANY
- server.sin_family AF_INET
- /
- Get the service port associated with this
process - usually in some /etc/ config file such as
/etc/services / - servent_p getservbyname ( PMSERVICE, tcp )
- server.sin_port servent_p-gts_port
11DNS library functions gethostbyname
- include ltnetdb.hgt
- struct hostent gethostbyname(
- const char hostname)
struct hostent char h_name char
h_aliases int h_addrtype int
h_length char h_addr_list
12hostent
Official Name
- h_name
- h_aliases
- h_addrtype
- h_length
- h_addr_list
alias 1
alias 2
null
h_addr_list0
(IP address 1)
h_addr_list1
(IP address 2)
null
All the IP addresses returned via the hostent
are in network byte order
define h_addr h_addr_list0
13DNS library functions gethostbyname
- On error gethostbyname return null.
- gethostbyname sets the global variable h_errno to
indicate the exact error - HOST_NOT_FOUND
- TRY_AGAIN
- NO_RECOVERY
- NO_DATA
- NO_ADDRESS
14Getting host IP address
- char h_addr_list
- h gethostbyname(hawk.depaul.edu")
- memcpy(sockaddr.sin_addr,
- h-gth_addr_list0,
- sizeof(struct in_addr))
15DNS library functions gethostbyaddr
- struct hostent gethostbyaddr(
- const char addr
- size_t len,
- int family)
16Other DNS library functions
- Shell Command uname n
- get hostname of local host
- uname a prints all info local host
- getservbyname
- get port number for a named service
- getservbyaddr
- get name for service associated with a port number
17Name/Address Conversion
- Protocol dependent DNS library functions
- gethostbyname
- gethostbyaddr
- Posix protocol independent functions
- getaddrinfo()
- getnameinfo()
- getaddrinfo()and getnameinfo() functions provide
name/address conversions as part of the sockets
library. - designed to support writing code that can run on
many protocols (IPv4, IPv6)
18POSIX getaddrinfo()
- int getaddrinfo(
- const char hostname,
- const char service,
- const struct addrinfo hints,
- struct addrinfo result)
- hostname is a hostname or an address string
(dotted decimal string for IP). - service is a service name or a decimal port
number string. - getaddrinfo()
- provides the combined functionality of
gethostbyname() and getservbyname()
19POSIX getaddrinfo()
- result is returned with the address of a pointer
to an addrinfo structure that is the head of a
linked list.
- struct addrinfo
- int ai_flags
- int ai_family
- int ai_socktype
- int ai_protocol
- size_t ai_addrlen
- char canonname
- struct sockaddr ai_addr
- struct addrinfo ai_next
used by socket()
used by bind() connect() sendto()
20POSIX getnameinfo()
- int getnameinfo(
- const struct sockaddr sockaddr,
- socklen_t addrlen
- char host,
- size_t hostlen,
- char serv,
- size_t servlen,
- int flags)
- getnameinfo() looks up a hostname and a
service name given a sockaddr
21TCP Client Design
- Identify and establish server address (IP and
port). - Allocate a socket.
- Request OS to use any valid local port and IP
address - Call connect()
- Communicate with server (read,write).
- Close the connection.
22Stream Socket Transaction (TCP Connection)
23Closing a TCP socket
- Many TCP based application protocols support
multiple requests and/or variable length requests
over a single TCP connection. - How does the server known when the client is
done ? - When it is safe to close the socket?
24Partial Close
- One solution is for the client to shut down only
its writing end of the socket. - The shutdown() system call provides this
function. - shutdown( int s, int direction)
- direction can be 0 to close the reading end or 1
to close the writing end. - shutdown sends info to the other process
25TCP Sockets Programming
- Typical issues
- reads dont correspond to writes.
- synchronization (including close())
- TCP Reads
- Each call to read() on a TCP socket returns any
available data (up to a maximum). - TCP buffers data at both ends of the connection.
26UDP Client Design
- Identify and establish the server address (IP and
port). - Allocate a socket.
- Request OS to use any valid local port and IP
address - Communicate with server (send, recv)
- Close the socket.
27Datagram Socket Transaction (UDP Connection)
Server
Client
socket()
socket()
bind()
sendto()
data
recvfrom()
data
sendto()
recvfrom()
close()
28Datagram Sockets
- Connectionless sockets, i.e., C/S addresses are
passed along with each message sent from one
process to another - Peer-to-Peer Communication
- Provides an interface to the UDP datagram
services - Handles network transmission as independent
packets - Provides no guarantees, although it does include
a checksum - Does not detect duplicates
- Does not determine sequence
- ie information can be lost, wrong order or
duplicated
29Daemons
- Most servers run as a daemon process
- Typical UNIX daemons
- Web server (httpd)
- Mail server (sendmail)
- SuperServer (inetd)
- System logging (syslogd)
- Print server (lpd)
- router process (routed, gated)
30Daemon Process
- A daemon is a process that
- runs in the background
- not associated with any terminal
- output doesn't end up in another session.
- ignore SIGINT (such as terminal generated signals
- C - since is not associated with any terminal uses
- file system
- central logging facility
- daemons should close all unnecessary descriptors
- often including stdin, stdout, stderr.
- daemons often change working directory.
- A background process
- Parent process fork() and then the parent exit().
- A way to disassociate a process from a terminal.
- Call setsid() and then fork() again.
31Daemon Process Init Example
- include ltsys/types.hgt
- include ltsys/stat.hgt
- include ltfcntl.hgt
- int
- daemon_init(void)
-
- pid_t pid
- if ( (pid fork()) lt 0)
- return(-1)
- else if (pid ! 0)
- exit(0) / parent is gone /
- / child continues /
- setsid() / become session leader /
- system(cd /") / change working directory /
- umask(0) / clear our file mode creation mask
/
32Performance issues with daemons processes
- CPU utilization
- There can be many servers running as daemons -and
idle most of the time. - Memory utilization
- Most daemons/servers are suspended most of the
time, but still occupy space in the process
table. - A solution Superserver or
- inetd (Internet services daemon )
33inetd
- the SuperServer is named inetd.
- inetd daemon creates multiple sockets and waits
for (multiple) incoming requests. - inetd typically uses select to watch multiple
sockets for input. - when a request arrives, inetd will fork and the
child process handles the client. - inetd child process closes all unnecessary
sockets. - inetd child dups the client socket to
descriptors 0,1 and 2 (stdin, stdout, stderr). - inetd child execs the real server program, which
handles the request and exits.
34inetd based servers
- Servers that are started by inetd assume that the
socket holding the request is already established
(descriptors 0,1 or 2). - TCP servers started by inetd dont call accept,
so they must call getpeername if they need to
know the address of the client. - inetd reads a configuration file that lists all
the services it should handle. - /etc/inetd.conf
- inetd creates a socket for each listed service,
and adds the socket to a fd_set given to
select().
35getpeername
- include ltsys/types.hgt
- include ltsys/socket.hgt
-
- int getpeername(int s,
- struct sockaddr name,
- socklen_t namelen)
- getpeername() returns the name of the peer
connected to socket s. -
36inetd service specification
- For each service, inetd needs to know
- the socket type and transport protocol
- wait/nowait flag.
- login name the process should run as.
- pathname of real server program.
- command line arguments to server program.
- Servers that are expected to deal with frequent
requests are typically not run from inetd - mail, web, NFS.
37Example /etc/inetd.conf
- Syntax for socket-based Internet services
- ltservice_namegt ltsocket_typegt ltprotogt ltflagsgt
ltusergt ltserver_pathnamegt ltargsgt -
- comments start with
- echo stream tcp nowait root internal
- echo dgram udp wait root internal
- chargen stream tcp nowait root internal
- chargen dgram udp wait root internal
- ftp stream tcp nowait root
/usr/sbin/ftpd ftpd -l - telnet stream tcp nowait root
/usr/sbin/telnetd telnetd - finger stream tcp nowait root
/usr/sbin/fingerd fingerd - Authentication
- auth stream tcp nowait nobody
/usr/sbin/in.identd in.identd -l -e -o - TFTP
- tftp dgram udp wait root /usr/sbin/tftpd
tftpd -s /tftpboot
38wait/nowait
- WAIT specifies that inetd should not look for new
clients for the service until the child (the real
server) has terminated. - TCP servers usually specify nowait - this means
inetd can start multiple copies of the TCP server
program - providing concurrency - Most UDP services run with inetd told to wait
until the child server has died.
39Topic
- Socket Options (discussion will continue in a
next lecture)
40Socket Options
- Various attributes that are used to determine the
behavior of sockets. - Setting options tells the OS/Protocol Stack the
behavior we want. - Support for generic options (apply to all
sockets) and protocol specific options.
41Option types
- Many socket options are Boolean flags indicating
whether some feature is enabled (1) or disabled
(0). - Other options are associated with more complex
types including int, timeval, in_addr, sockaddr,
etc.
42Read-Only Socket Options
- Some options are readable only (we cant set the
value).
43Setting and Getting option values
- include ltsys/socket.hgt
- getsockopt() gets the current value of a socket
option. - setsockopt() is used to set the value of a socket
option.
44getsockopt()
- int getsockopt( int sockfd,
- int level,
- int optname,
- void opval,
- socklen_t optlen)
- level specifies whether the option is a general
option or a protocol specific option (what level
of code should interpret the option).
45setsockopt()
- int setsockopt( int sockfd,
- int level,
- int optname,
- const void opval,
- socklen_t optlen)
46General Options
- Protocol independent options.
- Handled by the generic socket system code.
- Some general options are supported only by
specific types of sockets (SOCK_DGRAM,
SOCK_STREAM).
47Some Generic Options
- SO_BROADCAST
- SO_DONTROUTE
- SO_ERROR
- SO_KEEPALIVE
- SO_LINGER
- SO_RCVBUF,SO_SNDBUF
- SO_REUSEADDR
48SO_BROADCAST
- Boolean option enables/disables sending of
broadcast messages. - Underlying data layer must support broadcasting
- Applies only to SOCK_DGRAM sockets.
- Prevents applications from inadvertently sending
broadcasts (OS looks for this flag when broadcast
address is specified).
49SO_DONTROUTE
- Boolean option enables bypassing of normal
routing. - Used by routing daemons.
50SO_ERROR
- Integer value option.
- The value is an error indicator value (similar
to errno). - Readable only
- Reading (by calling getsockopt()) clears any
pending error.
51SO_KEEPALIVE
- Boolean option enabled means that STREAM sockets
should send a probe to peer if no data flow for a
long time. - Used by TCP - allows a process to determine
whether peer process/host has crashed. - Consider what would happen to an open telnet
connection without keepalive.
52SO_LINGER
- Value is of type
- struct linger
- int l_onoff / 0 off /
- int l_linger / time in seconds /
-
- Used to control whether and how long a call to
close will wait for pending ACKS. - connection-oriented sockets only.
53SO_LINGER usage
- By default, calling close() on a TCP socket will
return immediately. - The closing process has no way of knowing whether
or not the peer received all data. - Setting SO_LINGER means the closing process can
determine that the peer machine has received the
data (but not that the data has been read() !).
54shutdown() vs SO_LINGER
- How you can use shutdown() to find out when the
peer process has read all the sent data see
R.Stevens, 7.5
55TCP Connection Termination
Server
Client
FIN SNX
1
write close close returns
Data queued By TCP
ACKX1
2
Application Reads queued data and FIN close
...
FIN SNY
3
ACKY1
4
56TCP Connection Termination close w/ SO_LINGER
Server
Client
FIN SNX
1
write close close returns
Data queued By TCP
ACKX1
2
App. Reads queued data and FIN close
...
FIN SNY
3
ACKY1
4
57TCP Connection Termination w/ shutdown
Server
Client
FIN SNX
1
write shutdown WRITE read blocks read
returns 0
Data queued By TCP
ACKX1
2
App. Reads queued data and FIN close
...
FIN SNY
3
ACKY1
4
58SO_RCVBUF and SO_SNDBUF
- Integer values options - change the receive and
send buffer sizes. - Can be used with STREAM and DGRAM sockets.
- With TCP, this option effects the window size
used for flow control - must be established
before connection is made.
59SO_REUSEADDR
- Boolean option enables binding to an address
(port) that is already in use. - Used by servers that are transient - allows
binding a passive socket to a port currently in
use (with active sockets) by other processes.
(see example from lecture 4 Performance
Management server) - Can be used to establish separate servers for the
same service on different interfaces (or
different IP addresses on the same interface). - Virtual Web Servers can work this way.
60IP Options (IPv4)
- IP_HDRINCL used on raw IP sockets when we want
to build the IP header ourselves. - IP_TOS allows us to set the Type-of-service
field in an IP header. - IP_TTL allows us to set the Time-to-live field
in an IP header.
61TCP socket options
- TCP_KEEPALIVE set the idle time used when
SO_KEEPALIVE is enabled. - TCP_MAXSEG set the maximum segment size sent by
a TCP socket.
62TCP socket options
- TCP_NODELAY can disable TCPs Nagle algorithm
that delays sending small packets if there is
unACKd data pending. - TCP_NODELAY also disables delayed ACKS (TCP ACKs
are cumulative).