Socket programming Goal: learn how to build client/server application that communicate using sockets Socket API introduced in BSD4.1 UNIX, 1981 explicitly created, used, released by apps client/server paradigm two types of transport service via socket API: unreliable datagram reliable, byte streamoriented socket a host-local, application-created, OS-controlled interface (a door ) into which application process can both send and receive messages to/from another application process 2: Application Layer 1 What is a socket? An interface between application and network The application creates a socket The socket type dictates the style of communication reliable vs. best effort connection-oriented vs. connectionless Once configured the application can pass data to the socket for network transmission receive data from the socket (transmitted through the network by some other host) 2: Application Layer 2
Two essential types of sockets SOCK_STREAM a.k.a. TCP reliable delivery in-order guaranteed connection-oriented bidirectional App SOCK_DGRAM a.k.a. UDP unreliable delivery no order guarantees no notion of connection app indicates dest. for each packet can send or receive 3 2 1 socket Dest. App D1 3 2 1 socket D2 D3 2: Application Layer 3 Stream jargon A stream is a sequence of characters that flow into or out of a process. An input stream is attached to some input source for the process, eg, keyboard or socket. An output stream is attached to an output source, eg, monitor or socket. 2: Application Layer 4
A Socket-eye view of the Internet css3a0.engr.ccny.cuny.edu Aliases:csfhome.engr.ccny.cuny.edu (134.74.112.43) newworld.cs.umass.edu (128.119.245.93) Each host machine has an IP address When a packet arrives at a host 2: Application Layer 5 Ports Each host has 65,536 Port 0 ports Port 1 Some ports are reserved for specific Port 65535 apps 20,21: FTP A socket provides an interface 23: Telnet to send data to/from the 80: HTTP network through a port see RFC 1700 (about 2000 ports are reserved) 2: Application Layer 6
Addresses, Ports and Sockets Like apartments and mailboxes You are the application Your apartment building address is the address Your mailbox is the port The post-office is the network The socket is the key that gives you access to the right mailbox (one difference: assume outgoing mail is placed by you in your mailbox) Q: How do you choose which port a socket connects to? 2: Application Layer 7 Socket programming with TCP Socket: a door between application process and endend-transport protocol (UCP or TCP) TCP service: reliable transfer of bytes from one process to another controlled by application developer controlled by operating system process socket TCP with buffers, variables internet process socket TCP with buffers, variables controlled by application developer controlled by operating system host or server host or server 2: Application Layer 8
Socket programming with TCP Client must contact server server process must first be running server must have created socket (door) that welcomes client s contact Client contacts server by: creating client-local TCP socket specifying IP address, port number of server process When client creates socket: client TCP establishes connection to server TCP 2: Application Layer 9 Socket programming with TCP When contacted by client, server TCP creates new socket for server process to communicate with client allows server to talk with multiple clients source port numbers used to distinguish clients (more in Chap 3) client process three-way handshake application viewpoint TCP provides reliable, in-order transfer of bytes ( pipe ) between client and server server welcoming TCP socket server process client TCP socket byte pipe server connection TCP socket 2: Application Layer 10
Socket programming with TCP Example client-server app: 1) client reads line from standard input (infromuser stream), sends to server via socket (outtoserver stream) 2) server reads line from socket 3) server converts line to uppercase, sends back to client 4) client reads, prints modified line from socket (infromserver stream) Client Process process keyboard infromuser input stream output stream outtoserver monitor infromserver client TCP clientsocket socket input stream TCP socket to network from network 2: Application Layer 11 Client/server socket interaction: TCP Server (running on hostid) create socket, port=x, for incoming request: welcomesocket = ServerSocket() TCP wait for incoming connection request connection setup connectionsocket = welcomesocket.accept() read request from connectionsocket write reply to connectionsocket close connectionsocket Client create socket, connect to hostid, port=x clientsocket = Socket() send request using clientsocket read reply from clientsocket close clientsocket 2: Application Layer 12
Example: Java client (TCP) import java.io.*; import java.net.*; class TCPClient { Create input stream Create client socket, connect to server Create output stream attached to socket public static void main(string argv[]) throws Exception { String sentence; String modifiedsentence; BufferedReader infromuser = new BufferedReader(new InputStreamReader(System.in)); Socket clientsocket = new Socket("hostname", 6789); DataOutputStream outtoserver = new DataOutputStream(clientSocket.getOutputStream()); 2: Application Layer 13 Example: Java client (TCP), cont. Create input stream attached to socket Send line to server Read line from server BufferedReader infromserver = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); sentence = infromuser.readline(); outtoserver.writebytes(sentence + '\n'); modifiedsentence = infromserver.readline(); System.out.println("FROM SERVER: " + modifiedsentence); clientsocket.close(); } } 2: Application Layer 14
Example: Java server (TCP) import java.io.*; import java.net.*; class TCPServer { Create welcoming socket at port 6789 Wait, on welcoming socket for contact by client Create input stream, attached to socket public static void main(string argv[]) throws Exception { String clientsentence; String capitalizedsentence; ServerSocket welcomesocket = new ServerSocket(6789); while(true) { Socket connectionsocket = welcomesocket.accept(); BufferedReader infromclient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream())); 2: Application Layer 15 Example: Java server (TCP), cont Create output stream, attached to socket Read in line from socket Write out line to socket } } } DataOutputStream outtoclient = new DataOutputStream(connectionSocket.getOutputStream()); clientsentence = infromclient.readline(); capitalizedsentence = clientsentence.touppercase() + '\n'; outtoclient.writebytes(capitalizedsentence); End of while loop, loop back and wait for another client connection 2: Application Layer 16
Socket programming with UDP UDP: no connection between client and server no handshaking sender explicitly attaches IP address and port of destination to each packet server must extract IP address, port of sender from received packet application viewpoint UDP provides unreliable transfer of groups of bytes ( datagrams ) between client and server UDP: transmitted data may be received out of order, or lost 2: Application Layer 17 Client/server socket interaction: UDP Server (running on hostid) Client create socket, port=x, for incoming request: serversocket = DatagramSocket() read request from serversocket create socket, clientsocket = DatagramSocket() Create, address (hostid, port=x, send datagram request using clientsocket write reply to serversocket specifying client host address, port number read reply from clientsocket close clientsocket 2: Application Layer 18
Example: Java client (UDP) keyboard monitor Client Process process Output: sends packet (TCP sent byte stream ) input stream UDP packet infromuser sendpacket receivepacket client UDP clientsocket socket UDP packet UDP socket Input: receives packet (TCP received byte stream ) to network from network 2: Application Layer 19 Example: Java client (UDP) Create input stream Create client socket Translate hostname to IP address using DNS import java.io.*; import java.net.*; class UDPClient { public static void main(string args[]) throws Exception { BufferedReader infromuser = new BufferedReader(new InputStreamReader(System.in)); DatagramSocket clientsocket = new DatagramSocket(); InetAddress IPAddress = InetAddress.getByName("hostname"); byte[] senddata = new byte[1024]; byte[] receivedata = new byte[1024]; String sentence = infromuser.readline(); senddata = sentence.getbytes(); 2: Application Layer 20
Example: Java client (UDP), cont. Create datagram with data-to-send, length, IP addr, port Send datagram to server Read datagram from server } DatagramPacket sendpacket = new DatagramPacket(sendData, senddata.length, IPAddress, 9876); clientsocket.send(sendpacket); DatagramPacket receivepacket = new DatagramPacket(receiveData, receivedata.length); clientsocket.receive(receivepacket); String modifiedsentence = new String(receivePacket.getData()); System.out.println("FROM SERVER:" + modifiedsentence); clientsocket.close(); } 2: Application Layer 21 Example: Java server (UDP) import java.io.*; import java.net.*; Create datagram socket at port 9876 Create space for received datagram Receive datagram class UDPServer { public static void main(string args[]) throws Exception { DatagramSocket serversocket = new DatagramSocket(9876); byte[] receivedata = new byte[1024]; byte[] senddata = new byte[1024]; while(true) { DatagramPacket receivepacket = new DatagramPacket(receiveData, receivedata.length); serversocket.receive(receivepacket); 2: Application Layer 22
Example: Java server (UDP), cont Get IP addr port #, of sender String sentence = new String(receivePacket.getData()); InetAddress IPAddress = receivepacket.getaddress(); int port = receivepacket.getport(); String capitalizedsentence = sentence.touppercase(); Create datagram to send to client Write out datagram to socket } } senddata = capitalizedsentence.getbytes(); DatagramPacket sendpacket = new DatagramPacket(sendData, senddata.length, IPAddress, port); serversocket.send(sendpacket); } End of while loop, loop back and wait for another datagram 2: Application Layer 23 Socket Creation in C: socket int s = socket(domain, type, protocol); s: socket descriptor, an integer (like a file-handle) domain: integer, communication domain e.g., PF_INET (IPv4 protocol) typically used type: communication type SOCK_STREAM: reliable, 2-way, connection-based service SOCK_DGRAM: unreliable, connectionless, other values: need root permission, rarely used, or obsolete protocol: specifies protocol (see file /etc/protocols for a list of options) - usually set to 0 NOTE: socket call does not specify where data will be coming from, nor where it will be going to it just creates the interface! 2: Application Layer 24
The bind function associates and (can exclusively) reserves a port for use by the socket int status = bind(sockid, &addrport, size); status: error status, = -1 if bind failed sockid: integer, socket descriptor addrport: struct sockaddr, the (IP) address and port of the machine (address usually set to INADDR_ANY chooses a local address) size: the size (in bytes) of the addrport structure 2: Application Layer 25 Connection setup: listen & accept Called by passive participant int status = listen(sock, queuelen); status: 0 if listening, -1 if error sock: integer, socket descriptor queuelen: integer, # of active participants that can wait for a connection listen is non-blocking: returns immediately int s = accept(sock, &name, &namelen); s: integer, the new socket (used for data-transfer) sock: integer, the orig. socket (being listened on) name: struct sockaddr, address of the active participant namelen: sizeof(name): value/result parameter must be set appropriately before call adjusted by OS upon return accept is blocking: waits for connection before returning 2: Application Layer 26
connect call int status = connect(sock, &name, namelen); status: 0 if successful connect, -1 otherwise sock: integer, socket to be used in connection name: struct sockaddr: address of passive participant namelen: integer, sizeof(name) connect is blocking 2: Application Layer 27 Sending / Receiving Data With a connection (SOCK_STREAM): int count = send(sock, &buf, len, flags); count: # bytes transmitted (-1 if error) buf: char[], buffer to be transmitted len: integer, length of buffer (in bytes) to transmit flags: integer, special options, usually just 0 int count = recv(sock, &buf, len, flags); count: # bytes received (-1 if error) buf: void[], stores received bytes len: # bytes received flags: integer, special options, usually just 0 Calls are blocking [returns only after data is sent (to socket buf) / received] 2: Application Layer 28
close When finished using a socket, the socket should be closed: status = close(s); status: 0 if successful, -1 if error s: the file descriptor (socket being closed) Closing a socket closes a connection (for SOCK_STREAM) frees up the port used by the socket 2: Application Layer 29 Typical Client Structure sd = socket( ) bind(sd) connect(sd,server) send (sd) rvcd (sd) close (sd) create a socket bind to port connect to server send request to server receive data from server close connection 2: Application Layer 30
Typical Server sd = socket( ) // create a socket bind(sd) // bind to port listen(sd,n) // listen to clients while(1) newsd= accept (sd) // accept connection from client rvcd (newsd) // receive request from client send (newsd) // send reply to client close (newsd ) //close connection 2: Application Layer 31 The struct sockaddr The generic: struct sockaddr { u_short sa_family; char sa_data[14]; }; sa_family specifies which address family is being used determines how the remaining 14 bytes are used The Internet-specific: struct sockaddr_in { short sin_family; u_short sin_port; struct in_addr sin_addr; char sin_zero[8]; }; sin_family = AF_INET sin_port: port # (0-65535) sin_addr: IP-address sin_zero: unused 2: Application Layer 32
Address and port byte-ordering Address and port are stored as integers u_short sin_port; (16 bit) in_addr sin_addr; (32 bit) struct in_addr { u_long s_addr; }; Problem: different machines / OS s use different word orderings little-endian: lower bytes first big-endian: higher bytes first these machines may communicate with one another over the network 128.119.40.12 Big-Endian machine 128 119 40 12 Little-Endian machine WRONG!!! 12.40.119.128 128 119 40 12 2: Application Layer 33 Solution: Network Byte-Ordering Defs: Host Byte-Ordering: the byte ordering used by a host (big or little) Network Byte-Ordering: the byte ordering used by the network always big-endian Any words sent through the network should be converted to Network Byte-Order prior to transmission (and back to Host Byte-Order once received) Q: should the socket perform the conversion automatically? Q: Given big-endian machines don t need conversion routines and little-endian machines do, how do we avoid writing two versions of code? 2: Application Layer 34
UNIX s byte-ordering funcs u_long htonl(u_long x); u_short htons(u_short x); u_long ntohl(u_long x); u_short ntohs(u_short x); htonl On big-endian machines, these routines do nothing On little-endian machines, they reverse the byte order Big-Endian 128.119.40.12 machine Little-Endian12 40 machine 128 119 40 12 128.119.40.12 119 128 119 40 12 128 119 40 12 ntohl Same code would have worked regardless of endianness of the two machines 2: Application Layer 35 Other useful functions bzero(char* c, int n): 0 s n bytes starting at c gethostname(char *name, int len): gets the name of the current host gethostbyaddr(char *addr, int len, int type): converts IP hostname to structure containing long integer inet_addr(const char *cp): converts dotted-decimal char-string to long integer inet_ntoa(const struct in_addr in): converts long to dotted-decimal notation Warning: check function assumptions about byteordering (host or network). Often, they assume parameters / return solutions in network byteorder 2: Application Layer 36
Release of ports Sometimes, a rough exit from a program (e.g., ctrl-c) does not properly free up a port Eventually (after a few minutes), the port will be freed To reduce the likelihood of this problem, include the following code: #include <signal.h> void cleanexit(){exit(0);} in socket code: signal(sigterm, cleanexit); signal(sigint, cleanexit); 2: Application Layer 37 Socket programming: references C-language tutorial (audio/slides): Unix Network Programming (J. Kurose), http://manic.cs.umass.edu/courses2.html Java-tutorials: All About Sockets (Sun tutorial), http://java.sun.com/docs/books/tutorial/networking/soc kets Socket Programming in Java: a tutorial (Java World), http://www.javaworld.com/javaworld/jw-12-1996/jw-12- sockets.html 2: Application Layer 38
Chapter 2: Summary Our study of network apps now complete! application service requirements: reliability, bandwidth, delay client-server paradigm Internet transport service model connection-oriented, reliable: TCP unreliable, datagrams: UDP specific protocols: HTTP FTP SMTP, POP, IMAP DNS socket programming content distribution caches, CDNs P2P 2: Application Layer 39 Chapter 2: Summary Most importantly: learned about protocols typical request/reply message exchange: client requests info or service server responds with data, status code message formats: headers: fields giving info about data data: info being communicated control vs. data msgs in-band, out-of-band centralized vs. decentralized stateless vs. stateful reliable vs. unreliable msg transfer complexity at network edge security: authentication 2: Application Layer 40