Client/Server Sockets Programming Issues Issues in Client Programming l Identifying the Server. l Looking up a IP address. l Looking up a well known port name. l Specifying a local IP address. l UDP client design. l TCP client design. Identifying the Server l Options: – hard-coded into the client program. – require that the user identify the server. – read from a configuration file. – use a separate protocol/network service. Identifying a TCP/IP server. l Need an IP address, protocol and port. – We 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. Host Names l IP Addresses are great for computers – IP address includes information used for routing. l IP addresses are tough for humans to remember. l IP addresses are impossible to guess. – ever guessed at the name of a WWW site? The Domain Name System l The domain name system is usually used to translate a host name into an IP address . l Domain names comprise a hierarchy so that names are unique, yet easy to remember. DNS Hierarchy Looking up a Domain Name l We want to convert a Domain Name to an IP address: struct *hostent gethostbyname( char *name ); l gethostbyname() returns the address of a structure that contains the IP address in network byte order. Services and Ports l Many services are available via “well known” addresses (names). l There is a mapping of service names to port numbers: struct *servent getservbyname( char *service, char *protocol ); l servent->s_port is the port number in network byte order. Specifying a Local Address l When a client creates and binds a socket it must specify a local port and IP address. l Typically a client doesn’t care what port it is on: haddr->port = 0; Local IP address l A client can also ask the operating system to take care of specifying the local IP address: haddr->sin_addr.s_addr= INADDR_ANY; UDP Client Design l Establish server address (IP and port). l Allocate a socket. l Specify that any valid local port and IP address can be used. l Communicate with server (send, recv) l Close the socket. Connected mode UDP l A UDP client can call connect() to establish the address of the server. l The UDP client can then use read() and write() or send() and recv(). l A UDP client using a connected mode socket can only talk to one server (using the connected-mode socket). TCP Client Design l Establish server address (IP and port). l Allocate a socket. l Specify that any valid local port and IP address can be used. l Call connect() l Communicate with server (read,write). l Close the connection. connect() retcode = connect( int s, struct sockaddr *addr, int addrlen); l The return value is 0 if OK, -1 means there was an error. l If connect is sucessfull the socket is ready for read() and write(). Closing a TCP socket l Many TCP based application protocols support multiple requests and/or variable length requests over a single TCP connection. l How does the server known when the client is done (and it is OK to close the socket) ? Partial Close l One solution is for the client to shut down only it’s writing end of the socket. l 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! TCP sockets programming l Common problem areas: – null termination of strings. – reads don’t correspond to writes. – synchronization (including close()). – ambiguous protocol. TCP Reads l Each call to read() on a TCP socket returns any available data (up to a maximum). l TCP buffers data at both ends of the connection. l You must be prepared to accept data 1 byte at a time from a TCP socket! Reading n bytes int readn( int sd, char *buf, int n) { int i=0; int cnt; while ( (i0) i+=cnt; return i; } Reading a line int readline( int sd, char *buf, int max) { int i=0; if (read(sd,buf,1)!=1) return(0); while (( buf[i]!=‘\n’) && (i