package winstone.nio;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
/**
* @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
* @version $Id: NioSocketServer.java,v 1.1 2006/08/27 14:22:32 rickknowles Exp $
*/
public class NioSocketServer implements Runnable {
private final static int LISTEN_PORT = 6475;
private Thread thread;
private Selector selector;
private ServerSocket serverSocket;
public NioSocketServer(boolean useNIO) throws IOException {
if (useNIO) {
ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.configureBlocking(false);
ServerSocket ss = ssc.socket();
ss.bind(new InetSocketAddress(LISTEN_PORT));
this.selector = Selector.open();
ssc.register(this.selector, SelectionKey.OP_ACCEPT);
} else {
this.serverSocket = new ServerSocket(LISTEN_PORT);
this.serverSocket.setSoTimeout(500);
}
this.thread = new Thread(this);
this.thread.setDaemon(true);
this.thread.start();
}
public void run() {
boolean interrupted = false;
while (!interrupted) {
try {
if (this.selector != null) {
nioLoop();
} else {
jioLoop();
}
interrupted = Thread.interrupted();
} catch (IOException err) {
err.printStackTrace();
interrupted = true;
}
}
this.thread = null;
}
private void nioLoop() throws IOException {
this.selector.select(500);
Set selectedKeys = this.selector.selectedKeys();
Iterator i = selectedKeys.iterator();
while (i.hasNext()) {
SelectionKey key = (SelectionKey) i.next();
if (key.isAcceptable()) {
ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
SocketChannel sc = ssc.accept();
sc.configureBlocking(false);
sc.register(this.selector, SelectionKey.OP_READ);
} else if (key.isReadable()) {
SocketChannel sc = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(10);
buffer.clear();
sc.read(buffer);
buffer.flip();
sc.write(buffer);
sc.close();
}
i.remove();
}
}
private void jioLoop() throws IOException {
Socket socket = null;
try {
socket = this.serverSocket.accept();
} catch (SocketTimeoutException err) {
}
if (socket != null) {
InputStream in = socket.getInputStream();
int pos = 0;
int read = 0;
byte buffer[] = new byte[10];
while ((pos < buffer.length) && ((read = in.read(buffer, pos, buffer.length - pos)) != -1)){
pos += read;
}
OutputStream out = socket.getOutputStream();
out.write(buffer, 0, pos);
in.close();
out.close();
socket.close();
}
}
public void stop() {
this.thread.interrupt();
}
public static void main(String argv[]) throws Exception {
String iterArg = argv.length > 1 ? argv[1] : "1000";
int ITERATION_COUNT = Integer.parseInt(iterArg);
boolean useNIO = argv.length > 0 && argv[0].equals("nio");
InetAddress LOCATION = InetAddress.getLocalHost();
System.out.println("Address: " + LOCATION);
NioSocketServer server = new NioSocketServer(useNIO);
Thread.sleep(1000);
long startTime = System.currentTimeMillis();
byte TEST_ARRAY[] = "1234567890".getBytes();
for (int n = 0; n < ITERATION_COUNT; n++) {
byte buffer[] = new byte[TEST_ARRAY.length];
Socket socket = new Socket(LOCATION, LISTEN_PORT);
socket.setSoTimeout(50);
OutputStream out = socket.getOutputStream();
out.write(TEST_ARRAY);
InputStream in = socket.getInputStream();
int read = 0;
int pos = 0;
while ((pos < buffer.length) && ((read = in.read(buffer, pos, buffer.length - pos)) != -1)){
pos += read;
}
in.close();
out.close();
socket.close();
// if (!Arrays.equals(TEST_ARRAY, buffer)) {
// throw new RuntimeException("in and out arrays are not equal");
// }
if (n % 500 == 0) {
System.out.println("Completed " + n + " iterations in " +
(System.currentTimeMillis() - startTime) + "ms");
}
}
System.out.println("Completed " + ITERATION_COUNT + " iterations in " +
(System.currentTimeMillis() - startTime) + "ms");
server.stop();
}
}