Books
in black and white
Main menu
Share a book About us Home
Books
Biology Business Chemistry Computers Culture Economics Fiction Games Guide History Management Mathematical Medicine Mental Fitnes Physics Psychology Scince Sport Technics
Ads

More Java Pitfalls Share Reactor - Daconta M,C.

Daconta M,C. More Java Pitfalls Share Reactor - Wiley publishing, 2003. - 476 p.
ISBN: 0-471-23751-5
Download (direct link): morejavapitfallssharereactor2003.pdf
Previous << 1 .. 10 11 12 13 14 15 < 16 > 17 18 19 20 21 22 .. 166 >> Next

001 /* ImageAnnotationServer1.java */
002 package org.javapitfalls.item2;
003
004 import java.util.*;
005 import java.io.*;
006 import java.nio.*;
007 import java.net.*;
008 import java.nio.channels.*;
Listing 2.4 ImageAnnotationServer1.java (continued)
28 Item 2
009 010 public class ImageAnnotationServer1
011 {
012 public static final int DEFAULT_IAS_PORT = 8999;
013 boolean done;
014 015 public ImageAnnotationServer1() throws Exception
016 {
017 this(DEFAULT_IAS_PORT);
018 }
019 020 public ImageAnnotationServer1(int port) throws Exception
021 {
022 acceptConnections(port);
023 }
024 025 public void acceptConnections(int port) throws Exception
026 {
027 // get the ServerSocketChannel
028 ServerSocketChannel ssc = ServerSocketChannel.open();
029 System.out.println("Received a: " + 2
ssc getClass().getName());
030
031 // get the ServerSocket on this channel
032 ServerSocket ss = ssc.socket();
033 034 // bind to the port on the local host
035 InetAddress address = InetAddress.getLocalHost();
036 InetSocketAddress sockAddress = new 2
InetSocketAddress(address, port);
037 ss.bind(sockAddress);
038
039 // set to non-blocking
040 ssc.configureBlocking(false);
041
042 // create a Selector to multiplex channels on
043 Selector theSelector = Selector.open();
044
045 // register this channel (for all events) with the 2
Selector
046 // NOTE -- how do we know which events are OK????
047 SelectionKey theKey = ssc.register(theSelector, 2
SelectionKey.OP_ACCEPT |
Listing 2.4 (continued)
NIO Performance and Pitfalls 29
048: SelectionKey.OP_READ |
049: SelectionKey.OP_CONNECT |
050: SelectionKey.OP_WRITE);
051:
052: while (theSelector.select() > 0)
053: {
054: // get the ready keys
055: Set readyKeys = theSelector.selectedKeys();
056: Iterator i = readyKeys.iterator();
057:
058: // Walk through the ready keys collection and
process datarequests.
059: while (i.hasNext())
060: {
061: // get the key
062: SelectionKey sk = (SelectionKey)i.next();
063:
064: if (sk.isConnectable())
065: {
066: System.out.println("is Connectable.");
067: }
// ... other checks removed for brevity
083: }
084: }
085: }
086:
087: public static void main(String [] args)
088: {
// ... argument check removed for brevity
094:
095: try
096: {
097: int p = Integer.parseInt(args[0]);
098: ImageAnnotationServer1 ias1 = new 2
ImageAnnotationServer1(p);
099: } catch (Throwable t)
100: {
101: t.printStackTrace();
102: }
103: }
104: }
105:
Listing 2.4 (continued)
30 Item 2
Let's walk through the logic in this program one step at a time. These follow the bold lines in Listing 2.4. The steps are as follows:
1. At line 28, the program opens the ServerSocketChannel. You do not directly instantiate a ServerSocketChannel. Instead, you get an instance of one from the Service Provider Interface classes for this channel type.
2. At line 32, the program gets the ServerSocket from the ServerSocketChannel. The connection between the original java.net classes (Socket and ServerSocket) and their respective channels is more intertwined than the relationship between the original IO streams and their respective channels. In this case, a ServerSocketChannel is not a bound connection to a port; instead, you must retrieve the ServerSocket and bind it to the network address and port. Without you blindly copying the example code, it is unintuitive when you must switch from channels to their IO counterparts.
3. At line 37, the program binds the local host and port to the server socket.
4. At line 40, we configure the ServerSocketChannel to be non-blocking. This means that a call to read or write on a socket from this channel will return immediately whether there is data available or not. For example, in blocking mode, the program would wait until there was data available to be read before returning. It is important to understand that you can use these selectable channels on both clients and servers. This is the chief benefit of non-blocking IOŚ your program never waits on the IO but instead is notified when it occurs. This concept of the program reacting to multiplexed data instead of waiting until it occurs is an implementation of the Reactor pattern [Schmidt 96]. Figure 2.2 is a UML diagram of the Reactor pattern.
Figure 2.2 The Reactor pattern.
NIO Performance and Pitfalls 31
The Reactor pattern demultiplexes concurrent events to one or more event handlers. The key participants in the pattern are handles and a synchronous event demultiplexer. A handle represents the object of the event. In the NIO package implementation of this pattern, the handle is represented by the SelectionKey class. Thus, in relation to network servers, a handle represents a socket channel. The synchronous event demultiplexer blocks awaiting for events to occur on a set of handles. A common example of such a demultiplexer is the Unix select() system call. In the NIO package implementation of this pattern, the Selector class performs the synchronous event demultiplexing. Lastly, the Event Handler interface (and specific implementation) implements an object hook for a specific event handling. In the NIO implementation, the SelectionKey performs the object hook operation by allowing you to attach an object via the attach() method and retrieve the object via the attachment!) method. Here is an example of attaching a Callback object to a key:
Previous << 1 .. 10 11 12 13 14 15 < 16 > 17 18 19 20 21 22 .. 166 >> Next