Java has many features to support networking using the java.net package, networking is a very large topic and I will only cover the very basics here, in futre i will extand this section to cover advanced topics. At the heart of Java networking is the socket which identifies an endpoint in a network. A socket can handle many clients at once and many different types of information, this is archieved through a port which is a numbered socket on a server/machine. The port listens for connections from other servers/machines once connected data can travel over the network (internet usually) between the two systems. The socket communication takes place via a protocols Transmission Control Protocol (TCP) and Internet Protocol (IP), basically data is broken down (encapsulated) into network packets that are passed between the systems, the systems then un-encapsulates the packets to retrieve the data for the application. Data is encapsulated by the application for example browsers use HTTP data and thus this data can be encapsulated into network packets and passed over the internet. Networking uses a number of protocols but the most common are below:
Although not a comprehensive coverage of networking lastly I want to talk about network addressing, networking uses IP addressing to be able to move network packets between each other, there are two types commonly used IPv4 (older and still commonly used) and IPv6 (newer), every computer/server that wishes to communicate over the network has a IP address, this address is generally made up of numbers that humans cannot remember very well, so to convert these numbers into something more meaningful we use somethang called domain names (www.datadisk.co.uk is a domain name), the domain name maps to a IP address.
Networking Classes and Interfaces
There a a number of classes and interfaces associated with networking, it builds on the Java I/O we have already discussed, it allows you to pass Objects over the network, Java supports both TCP and UDP.
Networking Classes | ||
Authentication | InetAddress | SocketAddress |
CacheRequest | InetSocketAddress | SocketImpl |
CacheResponse | InterfaceAddress | SocketPermission |
ContentHandler | JarURLConnection | StandardSocketOption |
CookieHandler | MulticastSocket | URI |
CookieManager | NetPermission | URL |
DatagramPacket | NetworkInterface | URLClassLoader |
DatagramSocket | PasswordAuthenication | URLConnection |
DatagramSocketImpl | Proxy | URLDecoder |
HttpCookie | ProxySelector | URLEncoder |
HttpURLConnection | ResponseCache | URLPermission |
IDN | SecureCacheResponse | URLStreamHandler |
Inet4Address | ServerSocket | |
Inet6Address | Socket | |
Networking Interfaces | ||
ContentHandlerFactory | FileNameMap | SocketOptions |
CookiePolicy | ProtocolFamily | URLStreamHandlerFactory |
CookieStore | SocketImplFactory | |
DatagramSocketImplFactory | SocketOption |
The InetAddress class is used to encapsulate both the IP address and the domain name, it can handle both IPv4 and IPv6 address, you use one of the factory methods to create a InetAddress Object. One point to remember is that the address is first looked up in local cache before going out to the internet to obtain it.
InetAddress example | public static void main(String[] args) throws UnknownHostException { \\ notice the UnknowHostException as not using try-catch InetAddress Address = InetAddress.getLocalHost(); System.out.println(Address); Address = InetAddress.getByName("www.datadisk.co.uk"); System.out.println(Address); InetAddress SW[] = InetAddress.getAllByName("www.bbc.co.uk"); for (int i=0; i < SW.length; i++) System.out.println(SW[i]); } Output --------------------------------------- DATADISK-DESKTOP/192.168.0.150 www.datadisk.co.uk/94.136.40.103 www.bbc.co.uk/212.58.237.253 www.bbc.co.uk/212.58.233.253 |
TCP/IP sockets are used to implement reliable, bidirectional, persistent, point-topoint, steam-based connections between systems on local networks or the internet. A socket can be used to connect to Java's I/O system. There are two types of sockets
Socket Example | int c; // Create a socket connected to internic.net, port 43, use try-with-resources try ( Socket s = new Socket("whois.internic.net", 43) ) { // Obtain input and output streams. InputStream in = s.getInputStream(); OutputStream out = s.getOutputStream(); // Construct a request string. String str = "google.com"; // Convert to bytes. byte buf[] = str.getBytes(); // Send request. out.write(buf); // Read and display response. while ((c = in.read()) != -1) { System.out.print((char) c); } } catch (IOException ex) { System.out.println(ex); } Output ---------------------------- Domain Name: GOOGLE.COM Registry Domain ID: 2138514_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.markmonitor.com Registrar URL: http://www.markmonitor.com Updated Date: 2019-09-09T15:39:04Z Creation Date: 1997-09-15T04:00:00Z Registry Expiry Date: 2028-09-14T04:00:00Z ... |
Uniform Resource Locator (URL)
The URL is used to identify locations on the internet (or local networks), you use them in your browser when moving from website to website, http://www.datadisk.co.uk is a URL example, you notice the http part which generally means the webserver application is running on port 80 and uses the HTTP protocol, you may also see https which is a secured version (encrypted data) of the HTTP procotol. You need watch for MalformedURLExceptions in your code.
URL example | public static void main(String[] args) throws MalformedURLException { // Notice the exception handler URL hp = new URL("http://www.datadisk.co.uk/main/java.htm"); System.out.println("Protocol: " + hp.getProtocol()); System.out.println("Port: " + hp.getPort()); // if you get -1 this means the port was explicity set System.out.println("Host: " + hp.getHost()); System.out.println("File: " + hp.getFile()); System.out.println("Ext:" + hp.toExternalForm()); } Output ----------------------------- Protocol: http Port: -1 Host: www.datadisk.co.uk File: /main/java.htm Ext:http://www.datadisk.co.uk/main/java.htm |
URLConnection example | int c; URL hp = new URL("http://www.datadisk.co.uk"); URLConnection hpCon = hp.openConnection(); // get date long d = hpCon.getDate(); if(d==0) System.out.println("No date information."); else System.out.println("Date: " + new Date(d)); // get content type System.out.println("Content-Type: " + hpCon.getContentType()); // get expiration date d = hpCon.getExpiration(); if(d==0) System.out.println("No expiration information."); else System.out.println("Expires: " + new Date(d)); // get last-modified date d = hpCon.getLastModified(); if(d==0) System.out.println("No last-modified information."); else System.out.println("Last-Modified: " + new Date(d)); // get content length long len = hpCon.getContentLengthLong(); if(len == -1) System.out.println("Content length unavailable."); else System.out.println("Content-Length: " + len); if(len != 0) { System.out.println("=== Content ==="); InputStream input = hpCon.getInputStream(); while (((c = input.read()) != -1)) { System.out.print((char) c); } input.close(); } else { System.out.println("No content available."); } Output -------------------------------- No date information. Content-Type: text/html No expiration information. No last-modified information. Content-Length: 974 ... |
HttpURLConnection | URL hp = new URL("http://www.datadisk.co.uk"); HttpURLConnection hpCon = (HttpURLConnection) hp.openConnection(); // Display request method. System.out.println("Request method is " + hpCon.getRequestMethod()); // Display response code. System.out.println("Response code is " + hpCon.getResponseCode()); // Display response message. System.out.println("Response Message is " + hpCon.getResponseMessage()); // Get a list of the header fields and a set of the header keys. Map<String, List<String>> hdrMap = hpCon.getHeaderFields(); Set<String> hdrField = hdrMap.keySet(); System.out.println("\nHere is the header:"); // Display all header keys and values.. for(String k : hdrField) { System.out.println("Key: " + k + " Value: " + hdrMap.get(k)); } Output -------------------------------- Request method is GET Response code is 200 Response Message is OK Here is the header: Key: null Value: [HTTP/1.1 200 OK] Key: Pragma Value: [no-cache] Key: Content-Length Value: [974] Key: Cache-control Value: [no-store] Key: Content-Type Value: [text/html] |
DataGrams uses the UDP protocol and as I mentioned above it is not as reliable as TCP, however it is idea in applications like monitoring, NTP, DNs, etc. Java uses two classes
You create a DatagramSocket either bound to a specific IP address/port or not, DatagramSocket has many methods that you can use to send, receive, getPort, etc.
DatagramPacket is created by specifying the buffer (at a minimum) and other attributes like IP address, port, etc, again this also has many methods that you can use.
Datagram example | public static int serverPort = 998; public static int clientPort = 999; public static int buffer_size = 1024; public static DatagramSocket ds; public static byte buffer[] = new byte[buffer_size]; public static void TheServer() throws Exception { int pos=0; while (true) { int c = System.in.read(); switch (c) { case -1: System.out.println("Server Quits."); ds.close(); return; case '\r': break; case '\n': ds.send(new DatagramPacket(buffer,pos, InetAddress.getLocalHost(),clientPort)); pos=0; break; default: buffer[pos++] = (byte) c; } } } public static void TheClient() throws Exception { while(true) { DatagramPacket p = new DatagramPacket(buffer, buffer.length); ds.receive(p); System.out.println(new String(p.getData(), 0, p.getLength())); } } public static void main(String[] args) throws Exception { if(args.length == 1) { ds = new DatagramSocket(serverPort); TheServer(); } else { ds = new DatagramSocket(clientPort); TheClient(); } } |
Establishing a Simple Server (Using Stream Sockets)
There are five steps to create a simple server in Java
Simple Server | import java.io.*; import java.net.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Server extends JFrame { private JTextField enter; private JTextArea display; ObjectOutputStream output; ObjectInputStream input; public Server() { super( "Server" ); Container c = getContentPane(); enter = new JTextField(); enter.setEnabled( false ); enter.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { sendData( e.getActionCommand() ); } } ); c.add( enter, BorderLayout.NORTH ); display = new JTextArea(); c.add( new JScrollPane( display ), BorderLayout.CENTER ); setSize( 300, 150 ); show(); } public void runServer() { ServerSocket server; Socket connection; int counter = 1; try { // Step 1: Create a ServerSocket. server = new ServerSocket( 5000, 100 ); while ( true ) { // Step 2: Wait for a connection. display.setText( "Waiting for connection\n" ); connection = server.accept(); display.append( "Connection " + counter + " received from: " + connection.getInetAddress().getHostName() ); // Step 3: Get input and output streams. output = new ObjectOutputStream( connection.getOutputStream() ); output.flush(); input = new ObjectInputStream( connection.getInputStream() ); display.append( "\nGot I/O streams\n" ); // Step 4: Process connection. String message = "SERVER>>> Connection successful"; output.writeObject( message ); output.flush(); enter.setEnabled( true ); do { try { message = (String) input.readObject(); display.append( "\n" + message ); display.setCaretPosition( display.getText().length() ); } catch ( ClassNotFoundException cnfex ) { display.append( "\nUnknown object type received" ); } } while ( !message.equals( "CLIENT>>> TERMINATE" ) ); // Step 5: Close connection. display.append( "\nUser terminated connection" ); enter.setEnabled( false ); output.close(); input.close(); connection.close(); ++counter; } } catch ( EOFException eof ) { System.out.println( "Client terminated connection" ); } catch ( IOException io ) { io.printStackTrace(); } } private void sendData( String s ) { try { output.writeObject( "SERVER>>> " + s ); output.flush(); display.append( "\nSERVER>>>" + s ); } catch ( IOException cnfex ) { display.append( "\nError writing object" ); } } public static void main( String args[] ) { Server app = new Server(); app.addWindowListener( new WindowAdapter() { public void windowClosing( WindowEvent e ) { System.exit( 0 ); } } ); app.runServer(); } } |
Establishing a Simple Client (Using Stream Sockets)
Simple Client | import java.io.*; import java.net.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Client extends JFrame { private JTextField enter; private JTextArea display; ObjectOutputStream output; ObjectInputStream input; String message = ""; public Client() { super( "Client" ); Container c = getContentPane(); enter = new JTextField(); enter.setEnabled( false ); enter.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { sendData( e.getActionCommand() ); } } ); c.add( enter, BorderLayout.NORTH ); display = new JTextArea(); c.add( new JScrollPane( display ), BorderLayout.CENTER ); setSize( 300, 150 ); show(); } public void runClient() { Socket client; try { // Step 1: Create a Socket to make connection. display.setText( "Attempting connection\n" ); client = new Socket( InetAddress.getByName( "127.0.0.1" ), 5000 ); display.append( "Connected to: " + client.getInetAddress().getHostName() ); // Step 2: Get the input and output streams. output = new ObjectOutputStream( client.getOutputStream() ); output.flush(); input = new ObjectInputStream( client.getInputStream() ); display.append( "\nGot I/O streams\n" ); // Step 3: Process connection. enter.setEnabled( true ); do { try { message = (String) input.readObject(); display.append( "\n" + message ); display.setCaretPosition( display.getText().length() ); } catch ( ClassNotFoundException cnfex ) { display.append( "\nUnknown object type received" ); } } while ( !message.equals( "SERVER>>> TERMINATE" ) ); // Step 4: Close connection. display.append( "Closing connection.\n" ); output.close(); input.close(); client.close(); } catch ( EOFException eof ) { System.out.println( "Server terminated connection" ); } catch ( IOException e ) { e.printStackTrace(); } } private void sendData( String s ) { try { message = s; output.writeObject( "CLIENT>>> " + s ); output.flush(); display.append( "\nCLIENT>>>" + s ); } catch ( IOException cnfex ) { display.append( "\nError writing object" ); } } public static void main( String args[] ) { Client app = new Client(); app.addWindowListener( new WindowAdapter() { public void windowClosing( WindowEvent e ) { System.exit( 0 ); } } ); app.runClient(); } } |