Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
TDC561 Network Programming Week 5: Client/Server Programming Aspects Client side: Server Side: Daemon, inetd. Identifying the Server; Specifying a local IP address; TCP client design, UDP client design. Socket Options ( discussion will continue in a next lecture ) Camelia Zlatea, PhD Email: [email protected] References 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 013-490012-X) – Chap. 7,11,12, 21,22 Network Programming (TDC561) Winter 2003 Page 2 Aspects 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 Network Programming (TDC561) Winter 2003 Page 3 Identifying 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. Network Programming (TDC561) Winter 2003 Page 4 Services 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->s_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->sin_addr.s_addr= htonl(INADDR_ANY); » Typically a randomly port available is assigned with: haddr->port = htons(0); Network Programming (TDC561) Winter 2003 Page 9 Example: 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->s_port; Network Programming (TDC561) Winter 2003 Page 10 DNS library functions: gethostbyname #include <netdb.h> struct hostent *gethostbyname( const char *hostname); struct hostent { char *h_name; char **h_aliases; int h_addrtype; int h_length; char **h_addr_list; }; Network Programming (TDC561) Winter 2003 Page 11 hostent h_name h_aliases h_addrtype h_length h_addr_list Official Name alias 1 alias 2 null h_addr_list[0] (IP address 1) h_addr_list[1] (IP address 2) null #define h_addr h_addr_list[0] Network Programming (TDC561) All the IP addresses returned via the hostent are in network byte order Winter 2003 Page 12 DNS 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 Network Programming (TDC561) Winter 2003 Page 13 Getting host IP address: char **h_addr_list; h = gethostbyname(“hawk.depaul.edu"); memcpy(&sockaddr.sin_addr, h->h_addr_list[0], sizeof(struct in_addr)); Network Programming (TDC561) Winter 2003 Page 14 DNS library functions: gethostbyaddr struct hostent *gethostbyaddr( const char *addr size_t len, int family); Network Programming (TDC561) Winter 2003 Page 15 Other 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 Network Programming (TDC561) Winter 2003 Page 16 Name/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) Network Programming (TDC561) Winter 2003 Page 17 POSIX: 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() Network Programming (TDC561) Winter 2003 Page 18 POSIX: 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; used by socket() int ai_socktype; int ai_protocol; size_t ai_addrlen; used by: char *canonname; bind() struct sockaddr *ai_addr; connect() struct addrinfo *ai_next; sendto() }; Network Programming (TDC561) Winter 2003 Page 19 POSIX: getnameinfo() int getnameinfo( const struct sockaddr *sockaddr, socklen_t addrlen char *host, size_t hostlen, char *serv, size_t servlen, int flags); getnameinfo() Network Programming (TDC561) looks up a hostname and a service name given a sockaddr Winter 2003 Page 20 TCP 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. Network Programming (TDC561) Winter 2003 Page 21 Stream Socket Transaction (TCP Connection) Server Client socket() bind() socket() listen() connect() 3-way handshake accept() write() data read() data write() read() close() Network Programming (TDC561) EOF read() Winter 2003 close() Page 22 Closing 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? Network Programming (TDC561) Winter 2003 Page 23 Partial Close One solution is for the client to shut down only it’s 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 Network Programming (TDC561) Winter 2003 Page 24 TCP Sockets Programming Typical issues : – reads don’t 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. Network Programming (TDC561) Winter 2003 Page 25 UDP 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. Network Programming (TDC561) Winter 2003 Page 26 Datagram Socket Transaction (UDP Connection) Server Client socket() socket() bind() sendto() data recvfrom() data sendto() recvfrom() close() Network Programming (TDC561) Winter 2003 Page 27 Datagram 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 Network Programming (TDC561) Winter 2003 Page 28 Daemons 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) Network Programming (TDC561) Winter 2003 Page 29 Daemon 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. Network Programming (TDC561) Winter 2003 Page 30 Daemon Process Init – Example #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int daemon_init(void) { pid_t pid; if ( (pid = fork()) < 0) return(-1); else if (pid != 0) exit(0); /* parent is gone */ setsid(); /* child continues */ /* become session leader */ system(“cd /"); umask(0); /* change working directory */ /* clear our file mode creation mask */ close(0); close(1); close(2); return(0); /* stdin, stdout, stderr */ } Network Programming (TDC561) Winter 2003 Page 31 Performance 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 ) Network Programming (TDC561) Winter 2003 Page 32 inetd 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 dup’s the client socket to descriptors 0,1 and 2 (stdin, stdout, stderr). inetd child exec’s the real server program, which handles the request and exits. Network Programming (TDC561) Winter 2003 Page 33 inetd 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 don’t 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(). Network Programming (TDC561) Winter 2003 Page 34 getpeername #include <sys/types.h> #include <sys/socket.h> int getpeername(int s, struct sockaddr *name, socklen_t *namelen); getpeername() returns the name of the peer connected to Network Programming (TDC561) socket s. Winter 2003 Page 35 inetd 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. Network Programming (TDC561) Winter 2003 Page 36 Example /etc/inetd.conf # Syntax for socket-based Internet services: # <service_name> <socket_type> <proto> <flags> <user> <server_pathname> <args> # # comments start echo stream echo dgram chargen stream chargen dgram ftp stream telnet stream finger stream # Authentication auth stream o # TFTP tftp dgram Network Programming (TDC561) with tcp udp tcp udp tcp tcp tcp # nowait wait nowait wait nowait nowait nowait root root root root root root root tcp nowait nobody udp wait root internal internal internal internal /usr/sbin/ftpd ftpd -l /usr/sbin/telnetd telnetd /usr/sbin/fingerd fingerd /usr/sbin/in.identd in.identd -l -e - /usr/sbin/tftpd tftpd -s /tftpboot Winter 2003 Page 37 wait/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. Network Programming (TDC561) Winter 2003 Page 38 Topic Socket Options (discussion will continue in a next lecture) Socket 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. Network Programming (TDC561) Winter 2003 Page 40 Option 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. Network Programming (TDC561) Winter 2003 Page 41 Read-Only Socket Options Some options are readable only (we can’t set the value). Network Programming (TDC561) Winter 2003 Page 42 Setting and Getting option values #include <sys/socket.h> getsockopt() gets the current value of a socket option. setsockopt() is used to set the value of a socket option. Network Programming (TDC561) Winter 2003 Page 43 getsockopt() 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). Network Programming (TDC561) Winter 2003 Page 44 setsockopt() int setsockopt( int sockfd, int level, int optname, const void *opval, socklen_t optlen); Network Programming (TDC561) Winter 2003 Page 45 General 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). Network Programming (TDC561) Winter 2003 Page 46 Some Generic Options SO_BROADCAST SO_DONTROUTE SO_ERROR SO_KEEPALIVE SO_LINGER SO_RCVBUF,SO_SNDBUF SO_REUSEADDR Network Programming (TDC561) Winter 2003 Page 47 SO_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). Network Programming (TDC561) Winter 2003 Page 48 SO_DONTROUTE Boolean option: enables bypassing of normal routing. Used by routing daemons. Network Programming (TDC561) Winter 2003 Page 49 SO_ERROR Integer value option. The value is an error indicator value (similar to errno). Readable only Reading (by calling getsockopt()) clears any pending error. Network Programming (TDC561) Winter 2003 Page 50 SO_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. Network Programming (TDC561) Winter 2003 Page 51 SO_LINGER Value is of type: struct linger { int l_onoff; int l_linger; }; /* 0 = off */ /* time in seconds */ Used to control whether and how long a call to close will wait for pending ACKS. connection-oriented sockets only. Network Programming (TDC561) Winter 2003 Page 52 SO_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() !). Network Programming (TDC561) Winter 2003 Page 53 shutdown() 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] Network Programming (TDC561) Winter 2003 Page 54 TCP Connection Termination Server Client write close close returns FIN SN=X Data queued By TCP 2 Application Reads queued data and FIN ... ACK=X+1 1 FIN SN=Y ACK=Y+1 Network Programming (TDC561) close 3 4 Winter 2003 Page 55 TCP Connection Termination close w/ SO_LINGER Server Client write close FIN SN=X ACK=X+1 1 Data queued By TCP 2 App. Reads queued data and FIN ... close returns FIN SN=Y ACK=Y+1 Network Programming (TDC561) close 3 4 Winter 2003 Page 56 TCP Connection Termination w/ shutdown Server Client write shutdown WRITE read blocks FIN SN=X Data queued By TCP 2 App. Reads queued data and FIN ... ACK=X+1 1 FIN SN=Y close 3 read returns 0 ACK=Y+1 Network Programming (TDC561) 4 Winter 2003 Page 57 SO_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. Network Programming (TDC561) Winter 2003 Page 58 SO_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. Network Programming (TDC561) Winter 2003 Page 59 IP 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. Network Programming (TDC561) Winter 2003 Page 60 TCP 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. Network Programming (TDC561) Winter 2003 Page 61 TCP socket options TCP_NODELAY: can disable TCP’s Nagle algorithm that delays sending small packets if there is unACK’d data pending. TCP_NODELAY also disables delayed ACKS (TCP ACKs are cumulative). Network Programming (TDC561) Winter 2003 Page 62