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
Distributed Systems 13. Java Sockets Simon Razniewski Faculty of Computer Science Free University of Bozen-Bolzano A.Y. 2015/2016 Inter-Process Communication • Methods for making remote processes or threads exchange data • Typically associated to the transport layer • Two main modes – Message passing Datagrams, UDP – Bidirectional channel Byte stream, TCP Socket • Endpoint of inter-process communication flow over a network • Communication is bidirectional – Provides “local” APIs to send/receive messages over a network • Send: typically asynchronous – The thread copies the message to a local buffer and then continues – The Transport Layer takes care of sending the message • Receive: typically synchronous (with timeout) – Asynchronous forms (polling/interrupt) are more difficult and can be anyway realized thanks to multithreading Sockets in JAVA • Sockets in JAVA: java.net package • Connectionless socket UDP – “symmetric”: DatagramSocket class • Connection-Oriented socket TCP – “asymmetric”: Socket class for client, ServerSocket for server – The connection is a full-duplex byte stream, but the two interacting processes are distinguished (client is proactive, server waits) Internet Sockets and Identifiers • Network protocol: IP • Given a Transport protocol (UDP, TCP) – Each socket endpoint is identified by (IP address,port number) – Hence, “globally”, each socket endpoint is univocally identified by the triple (IP address, port number, protocol type) – Yes, it is possible to use at the same time an IP address + port number with TCP and UDP • Message communication: between two T-entities using a protocol (source IP addr., source port no., target IP addr., target port no., protocol) Naming and Addressing • java.net.InetAddress represents an IP address • Provides conversions to/from logical names (DNS facilities) • Principal (static) method: InetAddress.getByName(<name>) – Returns an InetAddress starting from a string – <name>: IPv4, IPv6, logical name – Relies on the two subclasses Inet4Address and Inet6Address for managing IPv4 and IPv6 addresses – Throws UnknownHostException if no IP address matching <name> can be found • InetAddress.getAllByName(<logical_name>) returns a list of addresses associated to the same logical name Loopback Address and Testing • To test applications locally, one can use the “loopback address”: address of a virtual network interface representing the local host • Traffic sent to the loopback address is simply moved back to the source without any change • Loopback address – IP: 127.0.0.1 – Logical: localhost • Automatically used when we call InetAddress.getByName(null) or InetAddress.getLocalHost() Datagram Socket • Supports connectionless interaction among (remote) threads • The thread creates a local socket used to send/receive messages: local address + port number • The pair (local IP address, port number) is a InetSocketAddress • DatagramSocket() creates a socket bound to a wildcard socket address(“any” local IP address, “any” available port) • dsocket.bind(<socket address>) binds the socket to the specified socket address • dsocket.close() “close” the socket (cannot be used to send/receive messages anymore) Datagram Socket • Typical constructor DatagramSocket(int localPort, InetAddress localAddress) throws SocketException – Creates a new datagram socket that binds to the specified (address,port) socket address – Throws SocketException if • The IP Address cannot be assigned (not local) • Port is reserved (<1024) • Another socket is already bound to the socket address (address,port) – Throws SecurityException if there is a security manager forbidding the use of (address,port) Information Exchange • The unit of information to be sent/received is encapsulated into a DatagramPacket • The datagram packet contains – Payload information: the content • byte[] buf buffer for the content • int length how long is the content • int offset starting point inside the buffer – Control information: info about receiver/sender • SocketAddress or InetAddress + int (port) Sending a DatagramPacket • • • • New DatagramPacket created Socket address is set to the destination endpoint Information serialized as a buffer of bits Message composed by extracting a portion of the buffer buffer offset offset + length • Sequence of multiple sending by shifting the offset buffer split into datagrams • Sending: socket.send(<packet>) Receiving a DatagramPacket • New DatagramPacket created • Buffer of bits specified to state where to put the incoming information, with offset and length buffer offset offset + length • Sequence of multiple receives by shifting the offset possible • Receiving: socket.receive(<packet>) • When the receive operation is completed, the buffer is filled with the content, and the socketAddress of <packet> contains the sender endpoint infos Receiving a DatagramPacket • The receive operation is blocking thread waits forever • Possibility of associating a timeout to the socket socket.setSoTimeout(<millisecon ds>) • When the timeout expires, a java.net.SocketTimeoutException is triggered DatagramSocket and Connection • socket.connect(<remote socket address>) • What does it mean to “connect” a datagram socket? It is connectionless! • Connection provides some useful facilities (syntactic sugar) – For sending no need of specifying the destination information into the datagram packet (it is taken from the connection) – For receiving selective receive: only packets coming from the address specified in the connection are accepted • socket.disconnect() to reset this behavior Closing a DatagramSocket • Sockets in JAVA do not only have an impact at the application level, but they also use resources • It is therefore recommended to close them when they are not useful anymore – Resources are freed • Programming pattern DatagramSocket ds = null; try { <code, including the creation of ds> } finally { if (ds != null) ds.close(); } Conversions from/to bytes String s = “hello”; byte [] m = s.getBytes(); String s = new String(m, “UTF8”); Conversion (2) public class Conversions { public static byte[] fromInt(int n) throws IOException { ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream(); DataOutputStream dataOutputStream = new DataOutputStream(arrayOutputStream); dataOutputStream.writeInt(n); dataOutputStream.flush(); return arrayOutputStream.toByteArray(); } public static int toInt(byte[] buf) throws IOException { ByteArrayInputStream arrayInputStream = new ByteArrayInputStream(buf); DataInputStream dataInputStream = new DataInputStream(arrayInputStream); return dataInputStream.readInt(); } } http://stackoverflow.com/questions/6374915/java-convert-int-to-byte-array-of-4-bytes TCP Sockets Java Stream Sockets • Connection-oriented reliable byte streams • Two kinds of stream sockets – java.net.Socket used by Client and Server – java.net.ServerSocket used only by the Server to accept connections from the clients • Guiding principle: classes tend to hide the protocol-related information just passed to the constructor • Remember: each connection is denoted by protocol (TCP) + socket addresses of the endpoints Client Socket • Needs – Socket address of the server – Port number of the client (if = 0 chosen by the system) • When created, atomically connects to the server – Throws IOException in case of problems or when the server cannot be contacted Client Socket – Connection Creation • public Socket(InetAddress remoteHost, int remotePort) throws IOException – Creates client socket connecting it to the provided remote socket address • public Socket (String remoteHost, int remotePort) throws IOException – Creates client socket connecting it to the remote socket address obtained after having resolved the logical name of the remote host • public Socket(InetAddress remoteHost, int remotePort, InetAddress localHost, int localPort)throws IOException – Creates client socket connecting it to the two end-points – If localPort = 0, it is automatically assigned by the system • Socket creation automatically handles also the connection to the server (CONNECT primitive) – Transparent three-way handshake protocol Client Socket - Usage • Socket is bidirectional: provides two streams – One for receiving information (input stream) socket.getInputStream(); – One for sending information (output stream) socket.getOutputStream(); • Streams are simply byte streams the abstract classes java.io.InputStream and java.io.OutputStream are used Data Streams • Support the marshaling/unmarshaling of JAVA primitive types • Can be connected to the byte streams associated to the socket – Realization of interaction protocols by exchanging typed information DataInputStream in = new DataInputStream(clientSocket.getInputStream()); DataOutputStream out = new DataOutputStream(clientSocket.getOutputStream()); DataOutputStream String void writeUTF(String str) char void writeChar(int v) int void writeInt(int v) float void writeFloat(float v) DataInputStream String readUTF() char readChar() int readInt() float readFloat() UTF = Unified Transformation Format Primitive data types and their length: http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html Writing & Reading • Other useful patterns are… • out = new PrintWriter (socket.getOutputStream(),true); – PrintWriter is a Java Writer managing the printing of primitive types – “true” indicates autoflushing, applied when one of the println() methods is invoked – Otherwise, data may be buffered • in = new BufferedReader( new InputStreamReader(socket.getIntputStream()); – BufferedReader supports reading text line per line Server Socket – Connection Creation • Server socket is used by the server process to wait for connection requests from the clients • public ServerSocket(int localPort) throws IOException; – Create a server socket binding it to specified local port – BindException if the local port is busy • public ServerSocket (int localPort,int backlog,InetAddress bindAddr) – Explicit local IP address – Backlog is the size of the queue for incoming connection indications (connections requested but not yet accepted) Server Socket – Waiting… • public Socket accept() throws IOException; • States that the server is willing to accept incoming connection • If the accept queue is not empty, a request is accepted, otherwise the server waits for new connection requests (blocking) – Timeout can be set • When the request is processed, a dedicated Socket is created • Such a socket represents the real server’s endpoint for the connection with the client Sequential Server <serverSocket created> while(true) { Socket connSocket = serverSocket.accept(); <execute service using connSocket> socket.close(); } Parallel Server <serverSocket created> while(true) { Socket connSocket = serverSocket.accept(); ServiceThread t = new ServiceThread(connSocket); t.start(); //or put start in the //constructor of ServiceThread } N.B.: connSocket closed by the service thread Graceful Shutdown • socket.close() closes both the input and output stream of the socket • Possibility of closing only one side (typically the output one) • Typically, a process is responsible for the output direction – socket.shutdownOutput() disables the output stream for the socket – An IOException is thrown if the process tries to write – All data that were inserted before are still delivered to the other endpoint, then the TCP termination protocol is executed – It is still possible to receive data using the input stream of the socket