package edu.umd.hooka; import java.io.IOException; import java.net.InetSocketAddress; 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.HashMap; import java.util.Iterator; import org.apache.hadoop.io.Text; public class VocabServer implements Runnable { public static void main(String[] args) { try { VocabServer v = new VocabServer(4444); Thread t = new Thread(v); t.start(); try {Thread.sleep(10000); } catch (Exception e ) {} v.stopServer(); } catch (IOException e) { e.printStackTrace();} } ServerSocketChannel serverChannel; public VocabServer(int port) throws IOException { serverChannel = ServerSocketChannel.open(); selector = Selector.open(); serverChannel.socket().bind (new InetSocketAddress(port)); serverChannel.configureBlocking (false); serverChannel.register (selector, SelectionKey.OP_ACCEPT); System.err.println("Vocab server initialized on port " + port); } public void stopServer() { System.err.println("Stopping server..."); try { selector.close(); } catch (Exception e) { System.err.println("Caught " + e); } } Selector selector = null; Text t = new Text(); VocabularyWritable v = new VocabularyWritable(); public void run() { System.err.println("Vocab server running..."); while (true) { try { selector.select(); } catch (IOException e) { System.err.println("Caught exception in select()"); e.printStackTrace(); break; } if (selector.isOpen() == false) break; Iterator<SelectionKey> it = selector.selectedKeys().iterator(); while (it.hasNext()) { SelectionKey key = it.next(); try { processSelectionKey(key); } catch (IOException e) { key.cancel(); System.err.println("Caught exception handling selection key. Key cancelled"); } it.remove(); } } System.err.println("Server exiting."); System.err.println(" " + (v.size()-1) + " types processed"); System.err.println(" " + connections + " connections"); } ByteBuffer out_bb = ByteBuffer.allocate(4); int i = 0; int connections = 0; HashMap<SelectionKey, ByteBuffer> key2buf = new HashMap<SelectionKey, ByteBuffer>(); protected void processSelectionKey(SelectionKey key) throws IOException { if (key.isAcceptable()) { ServerSocketChannel server = (ServerSocketChannel) key.channel(); SocketChannel channel = server.accept(); if (channel == null) return; channel.configureBlocking (false); channel.register (selector, SelectionKey.OP_READ); connections++; } else if (key.isReadable()) { ByteBuffer in_bb = key2buf.get(key); if (in_bb == null) { System.err.println("Allocating new buffer!"); in_bb = ByteBuffer.allocate(2048); key2buf.put(key, in_bb); } SocketChannel sc = (SocketChannel)key.channel(); int num = sc.read(in_bb); if (num == -1) { System.out.println("closing"); key2buf.remove(key); sc.close(); return; } int elen = in_bb.get(0); if (elen < 1) throw new RuntimeException("Elen is out of bounds! elen="+elen); int pl = in_bb.position(); if (elen + 3 > pl) { // System.err.println("Haven't read enough! " + elen + " pos="+pl); return; // not ready! } else { // System.err.println("Read enough"); } in_bb.flip(); t.set(in_bb.array(), 2, in_bb.limit() - 2); i = v.addOrGet(t.toString()); //System.err.println(t.toString()); /*if (t.getLength() > 15) throw new RuntimeException("Too long!!");*/ out_bb.putInt(i); out_bb.flip(); int x = sc.write(out_bb); if (x != 4) throw new IOException("Failed to write 4 bytes!"); in_bb.rewind(); in_bb.limit(2048); out_bb.rewind(); } else if (key.isWritable()) { throw new IOException("Received writable socket - not expecting!"); } } }