Module 4 Advanced Java (Networking)
Module 4 Advanced Java (Networking)
To manage multiple client connections, a server process must be multithreaded or have some
other means of multiplexing the simultaneous I/O. Socket communication takes place via a
protocol. Internet Protocol (IP) is a low-level routing protocol that breaks data into small packets
and sends them to an address across a network, which does not guarantee to deliver said packets
to the destination. Transmission Control Protocol (TCP) is a higher-level protocol that manages
to robustly string together these packets, sorting and retransmitting them as necessary to reliably
transmit data. A third protocol, User Datagram Protocol (UDP), sits next to TCP and can be
used directly to support fast, connectionless, unreliable transport of packets. Once a connection
has been established, a higher-level protocol ensues, which is dependent on which port you are
using.
TCP/IP reserves the lower 1,024 ports for specific protocols. Many of these will seem familiar to
you if you have spent any time surfing the Internet. Port number 21 is for FTP; 23 is for Telnet;
25 is for e-mail; 43 is for whois; 79 is for finger; 80 is for HTTP; 119 is for netnews—and the
list goes on. It is up to each protocol to determine how a client should interact with the port.
When a client requests a file from an HTTP server, an action known as a hit, it simply sends the
name of the file in a special format to a predefined port and reads back the contents of the file.
The server also responds with a status code to tell the client whether or not the request can be
fulfilled and why.
A key component of the Internet is the address. Every computer on the Internet has one. An
Internet address is a number that uniquely identifies each computer on the Net. Originally, all
Internet addresses consisted of 32-bit values, organized as four 8-bit values. This address type
was specified by IPv4 (Internet Protocol, version 4). However, a new addressing scheme, called
IPv6 (Internet Protocol, version 6) has come into play. IPv6 uses a 128-bit value to represent an
address, organized into eight 16-bit chunks. Although there are several reasons for and
advantages to IPv6, the main one is that it supports a much larger address space than does IPv4.
Java supports TCP/IP both by extending the already established stream I/O interface introduced
in Chapter 19 and by adding the features required to build I/O objects across the network. Java
supports both the TCP and UDP protocol families. TCP is used for reliable stream-based I/O
across the network. UDP supports a simpler, hence faster, point-to-point datagram-oriented
model. The classes contained in the java.net package are shown here
InetAddress :
The InetAddress class is used to encapsulate both the numerical IP address and the domain
name for that address. InetAddress can handle both IPv4 and IPv6 addresses
Factory Methods
Three commonly used InetAddress factory methods are shown here:
The following example prints the addresses and names of the local machine and two well-known
Internet web sites:
// Demonstrate InetAddress.
import java.net.*;
class InetAddressTest
{
public static void main(String args[]) throws UnknownHostException {
InetAddress Address = InetAddress.getLocalHost();
System.out.println(Address);
Address = InetAddress.getByName("osborne.com");
System.out.println(Address);
InetAddress SW[] = InetAddress.getAllByName("www.nba.com");
for (int i=0; i<SW.length; i++)
System.out.println(SW[i]);
}
}
Instance Methods :
The InetAddress class has several other methods, which can be used on the objects returned by
the methods just discussed. Here are some of the more commonly used methods:
Socket defines several instance methods. For example, a Socket can be examined at any time for
the address and port information associated with it, by use of the following methods:
InetAddress getInetAddress( )
int getPort( )
int getLocalPort( )
You can gain access to the input and output streams associated with a Socket by use of the
getInputStream( ) and getOuptutStream( ) methods, as shown here.
// Demonstrate Sockets.
import java.net.*;
import java.io.*;
class Whois {
public static void main(String args[]) throws Exception {
int c;
// Create a socket connected to internic.net, port 43.
Socket s = new Socket("internic.net", 43);
// Obtain input and output streams.
InputStream in = s.getInputStream();
OutputStream out = s.getOutputStream();
String str = (args.length == 0 ? "osborne.com" : args[0]) + "\n";
// 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);
}
s.close();
}
}
First, a Socket is constructed that specifies the host name "internic.net" and the port number 43.
Internic.net is the InterNIC web site that handles whois requests. Port 43 is the whois port.
Next, both input and output streams are opened on the socket. Then, a string is constructed that
contains the name of the web site you want to obtain information about. The string is converted
into a byte array and then sent out of the socket.
URL :
The URL provides a reasonably intelligible form to uniquely identify or address information on
the Internet. URLs are ubiquitous; every browser uses them to identify information on the Web.
Within Java’s network class library, the URL class provides a simple, concise API to access
information across the Internet using URLs
import java.net.*;
class URLDemo {
public static void main(String args[]) throws MalformedURLException {
URL hp = new URL("http://www.osborne.com/downloads");
System.out.println("Protocol: " + hp.getProtocol());
System.out.println("Port: " + hp.getPort());
System.out.println("Host: " + hp.getHost());
System.out.println("File: " + hp.getFile());
System.out.println("Ext:" + hp.toExternalForm());
}
}
URL Connection :
URLConnection is a general-purpose class for accessing the attributes of a remote resource.
Once you make a connection to a remote server, you can use URLConnection to inspect the
properties of the remote object before actually transporting it locally.
The program establishes an HTTP connection to www.internic.net over port 80. It then displays
several header values and retrieves the content. Here are the first lines of the output (the precise
output will vary over time).
// Demonstrate HttpURLConnection.
import java.net.*;
import java.io.*;
import java.util.*;
class HttpURLDemo
{
public static void main(String args[]) throws Exception {
URL hp = new URL("http://www.google.com");
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));
}
}
}
The URI Class :
Arelatively recent addition to Java is the URI class, which encapsulates a Uniform Resource
Identifier (URI). URIs are similar to URLs. In fact, URLs constitute a subset of URIs. A URI
represents a standard way to identify a resource. AURL also describes how to access the
resource.
Cookies :
The java.net package includes classes and interfaces that help manage cookies and can be used
to create a stateful (as opposed to stateless) HTTP session. The classes are CookieHandler,
CookieManager, and HttpCookie. The interfaces are CookiePolicy and CookieStore. All but
CookieHandler was added by Java SE 6.
Datagrams :
TCP/IP-style networking is appropriate for most networking needs. It provides a serialized,
predictable, reliable stream of packet data. This is not without its cost, however. TCP includes
many complicated algorithms for dealing with congestion control on crowded networks, as well
as pessimistic expectations about packet loss. This leads to a somewhat inefficient way to
transport data. Datagrams provide an alternative.
Datagrams are bundles of information passed between machines. They are somewhat like a hard
throw from a well-trained but blindfolded catcher to the third baseman. Once the datagram has
been released to its intended target, there is no assurance that it will arrive or even that someone
will be there to catch it. Likewise, when the datagram is received, there is no assurance that it
hasn’t been damaged in transit or that whoever sent it is still there to receive a response.
Java implements datagrams on top of the UDP protocol by using two classes: the
DatagramPacket object is the data container, while the DatagramSocket is the mechanism
used to send or receive the DatagramPackets. Each is examined here.
DatagramSocket :
DatagramSocket defines four public constructors. They are shown here:
DatagramSocket defines many methods. Two of the most important are send( ) and receive( ),
which are shown here:
void send(DatagramPacket packet) throws IOException
void receive(DatagramPacket packet) throws IOException
The send( ) method sends packet to the port specified by packet. The receive method waits for a
packet to be received from the port specified by packet and returns the result.
Other methods give you access to various attributes associated with a DatagramSocket.
InetAddress getInetAddress( )
int getLocalPort( )
int getPort( )
boolean isBound( )
boolean isConnected( )
void setSoTimeout(int millis) throws SocketException
DatagramPacket:
A Datagram Example
The following example implements a very simple networked communications client and server.
// Demonstrate datagrams.
import java.net.*;
class WriteServer {
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.");
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();
}
}
}