Book Image

Learning Network Programming with Java

Book Image

Learning Network Programming with Java

Overview of this book

Network-aware applications are becoming more prevalent and play an ever-increasing role in the world today. Connecting and using an Internet-based service is a frequent requirement for many applications. Java provides numerous classes that have evolved over the years to meet evolving network needs. These range from low-level socket and IP-based approaches to those encapsulated in software services. This book explores how Java supports networks, starting with the basics and then advancing to more complex topics. An overview of each relevant network technology is presented followed by detailed examples of how to use Java to support these technologies. We start with the basics of networking and then explore how Java supports the development of client/server and peer-to-peer applications. The NIO packages are examined as well as multitasking and how network applications can address practical issues such as security. A discussion on networking concepts will put many network issues into perspective and let you focus on the appropriate technology for the problem at hand. The examples used will provide a good starting point to develop similar capabilities for many of your network needs
Table of Contents (16 chapters)
Learning Network Programming with Java
Credits
About the Author
About the Reviewer
www.PacktPub.com
Preface
Index

NIO support


The java.io, java.nio, and java.nio subpackages provide most of the Java support for IO processing. We will examine the support that these packages provide for network access in Chapter 3, NIO Support for Networking. Here, we will focus on the basic aspects of the java.nio package.

There are three key concepts used in the NIO package:

  • Channel: This represents a stream of data between applications

  • Buffer: This works with a channel to process data

  • Selector: This is a technology that allows a single thread to handle multiple channels

A channel and a buffer are typically associated with each other. Data may be transferred from a channel to a buffer or from a buffer to a channel. The buffer, as its name implies, is a temporary repository for information. The selector is useful in supporting application scalability, and this will be discussed in Chapter 7, Network Scalability.

There are four primary channels:

  • FileChannel: This works with a file

  • DatagramChannel: This supports UDP communications

  • SocketChannel: This is used with a TCP client

  • ServerSocketChannel: This is used with a TCP server

There are several buffer classes that support primitive data types, such as character, integer, and float.

Using the URLConnection class

A simple way of accessing a server is to use the URLConnection class. This class represents a connection between an application and a URL instance. A URL instance represents a resource on the Internet.

In the next example, a URL instance is created for the Google website. Using the URL class' openConnection method, a URLConnection instance is created. A BufferedReader instance is used to read lines from the connection that is then displayed:

    try {
        URL url = new URL("http://www.google.com");
        URLConnection urlConnection = url.openConnection();
        BufferedReader br = new BufferedReader(
                new InputStreamReader(
                    urlConnection.getInputStream()));
        String line;
        while ((line = br.readLine()) != null) {
            System.out.println(line);
        }
        br.close();
    } catch (IOException ex) {
        // Handle exceptions
    }

The output is rather lengthy, so only part of the first line is shown here:

<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" ...

The URLConnection class hides some of the complexity of accessing HTTP servers.

Using the URLConnection class with buffers and channels

We can rework the previous example to illustrate the use of channels and buffers. The URLConnection instance is created as before. We will create a ReadableByteChannel instance and then a ByteBuffer instance, as illustrated in the next example. The ReadableByteChannel instance allows us to read from the site using its read method. A ByteBuffer instance receives data from the channel and is used as the argument of the read method. The buffer created holds 64 bytes at a time.

The read method returns the number of bytes read. The ByteBuffer class' array method returns an array of bytes, which is used as the argument of the String class' constructor. This is used to display the data read. The clear method is used to reset the buffer so that it can be used again:

    try {
        URL url = new URL("http://www.google.com");
        URLConnection urlConnection = url.openConnection();
        InputStream inputStream = urlConnection.getInputStream();
        ReadableByteChannel channel = 
            Channels.newChannel(inputStream);
        ByteBuffer buffer = ByteBuffer.allocate(64);
        String line = null;
        while (channel.read(buffer) > 0) {
            System.out.println(new String(buffer.array()));
            buffer.clear();
        }
        channel.close();
    } catch (IOException ex) {
        // Handle exceptions
    }

The first line of output is shown next. This produces the same output as before, but it is restricted to displaying 64 bytes at a time:

<!doctype html><html itemscope="" itemtype="http://schema.org/We

The Channel class and its derived classes provide an improved technique to access data found on a network than data provided by older technologies. We will be seeing more of this class.