Name: bsC130419 Date: 06/21/2001
java version "1.4.0-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0
Java HotSpot(TM) Client VM (build 1.4.0-beta-b65, mixed mode)
In an attempt to write a small webserver test with two threads, one waiting on
SelectionKey.OP_ACCEPT and one waiting on SelectionKey.OP_READ and
SelectionKey.OP_WRITE:
Selector.selectNow() throws an exception if no ServerSocketChannel
has been registered
readSelector err: java.io.IOException: The parameter is incorrect
java.io.IOException: The parameter is incorrect
at sun.nio.ch.PollArrayWrapper.poll0(Native Method)
at sun.nio.ch.PollArrayWrapper.poll(Unknown Source)
at sun.nio.ch.SelectorImpl.doSelect(Unknown Source)
at sun.nio.ch.SelectorImpl.selectNow(Unknown Source)
at WebServer4.run(WebServer4.java:153)
It makes no difference if selectNow is only called after a normal SocketChannel
is registered. The problem is not present in select() or select(<timeout>)
********** Source: ***********
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.channels.spi.*;
import java.net.*;
import java.util.*;
public class WebServer4 extends Thread {
private static final int PORT = 8900;
protected boolean verbose=false;
protected int count=0;
Selector readSelector;
protected ByteBuffer readbuffer=ByteBuffer.allocateDirect(1024);
protected byte readbytes[]=new byte[1024];
protected ByteBuffer writebuffer=ByteBuffer.allocateDirect(2048);
/**
Constructor
*/
public WebServer4() throws Exception {
acceptConnections(PORT);
}
/**
Here it waits for the accept connections
*/
private void acceptConnections(int port) throws Exception {
System.out.println("Listening on "+port);
readSelector= SelectorProvider.provider().openSelector();
Selector acceptSelector = SelectorProvider.provider().openSelector();
// Create a new server socket and set to non blocking mode
ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.configureBlocking(false);
// Bind the server socket to the local host and port
InetAddress lh = InetAddress.getLocalHost();
InetSocketAddress isa = new InetSocketAddress(lh, port);
ssc.socket().bind(isa);
SelectionKey acceptKey = ssc.register(acceptSelector,
SelectionKey.OP_ACCEPT);
//This is the workaround!
/*
ServerSocketChannel ssc2 = ServerSocketChannel.open();
ssc2.configureBlocking(false);
SelectionKey dummyKey = ssc2.register(readSelector,
SelectionKey.OP_ACCEPT);
*/
start();
//Loop waiting for accept
do {
int keysAdded = acceptSelector.selectNow();
if (keysAdded<=0) {
try {
Thread.currentThread().sleep(10);
}
catch(Exception e) {
}
continue;
}
// Someone is ready for I/O, get the ready keys
Set readyKeys = acceptSelector.selectedKeys();
Iterator i = readyKeys.iterator();
// Walk through the ready keys collection and process date requests.
while (i.hasNext()) {
SelectionKey sk = (SelectionKey)i.next();
i.remove();
handleSelectionKey(sk,acceptSelector);
}
}
while(true);
}
/**
Handles selections coming from both the acceptselector and the readselector
*/
protected void handleSelectionKey(SelectionKey sk,Selector selector) {
try {
if (sk.isAcceptable()) {
ServerSocketChannel channel =
(ServerSocketChannel)sk.channel();
if (verbose)
System.out.println("Accept");
Socket s = channel.accept();
SocketChannel sc=s.getChannel();
sc.configureBlocking(false);
SelectionKey readKey = sc.register(readSelector,
SelectionKey.OP_READ|SelectionKey.OP_WRITE);
}
if (sk.isReadable()) {
if (verbose)
System.out.println("Read!");
handleRead(sk);
}
if (sk.isWritable()) {
if (verbose)
System.out.println("Write!");
handleWrite(sk);
}
if (sk.readyOps()==0) {
System.out.println("No ready ops!!");
}
}
catch(Exception e) {
if (e instanceof CancelledKeyException) {
}
else {
System.out.println("handleSelectionKey err: ");
e.printStackTrace();
}
}
}
// Entry point.
public static void main(String[] args) {
try {
WebServer4 nbt = new WebServer4();
} catch(Exception e) {
e.printStackTrace();
}
}
/**
The other thread waits here for read and write messages
*/
public void run() {
try {
//Loop waiting for read and write
do {
int keysAdded = readSelector.selectNow();
//int keysAdded = readSelector.select(10);
if (keysAdded<=0) {
try {
Thread.currentThread().sleep(10);
}
catch(Exception e) {
}
continue;
}
// Someone is ready for I/O, get the ready keys
Set readyKeys = readSelector.selectedKeys();
Iterator i = readyKeys.iterator();
// Walk through the ready keys collection and process date
requests.
while (i.hasNext()) {
SelectionKey sk = (SelectionKey)i.next();
i.remove();
handleSelectionKey(sk,readSelector);
}
}
while(true);
}
catch(Exception e) {
System.out.println("readSelector err: "+e);
e.printStackTrace();
}
}
protected void handleWrite(SelectionKey sk) {
try {
SocketChannel channel =
(SocketChannel)sk.channel();
}
catch(Exception e) {
System.out.println("handleWrite err: ");
e.printStackTrace();
}
}
protected void handleRead(SelectionKey sk) {
try {
SocketChannel channel =
(SocketChannel)sk.channel();
boolean read=false;
do {
readbuffer.rewind();
int n=channel.read(readbuffer);
if (n<=0) break;
read=true;
readbuffer.rewind();
readbuffer.get(readbytes);
String s=new String(readbytes,0,n);
if (verbose)
System.out.println("Got "+n+": "+s);
}
while(true);
writeToSocket(channel);
channel.close();
}
catch(Exception e) {
// System.out.println("handleRead err: ");
// e.printStackTrace();
}
}
/**
Writes to a socket channel
*/
protected void writeToSocket(SocketChannel channel) throws Exception {
count++;
String s2="<html><body>#"+count+"</body></html>";
String send = "HTTP/1.0 200 OK\n" +
"Allow: GET, POST\n"+
"MIME-Version: 1.0\n"+
"Content-Type: text/html\n"+
"Content-length: "+s2.length()+"\n\n"+
s2;
writebuffer.rewind();
for (int i=0;i<send.length();i++) {
writebuffer.put((byte)send.charAt(i));
}
writebuffer.rewind();
long time=System.currentTimeMillis();
int n=channel.write(writebuffer);
long time2=System.currentTimeMillis();
if (verbose)
System.out.println("String: "+send.length()+", written: "+n);
if (verbose)
System.out.println("Time taken: "+(time2-time));
if (n<send.length()) {
//mark the socket as waiting to be writable
//Should really add unsent data to a buffer.
}
}
}
(Review ID: 126936)
======================================================================