/** Selects on sockets and informs their Communicator when there is something to do. */ public void communicate(int timeout) { try { selector.select(timeout); } catch (IOException e) { // Not really sure why/when this happens yet return; } Iterator<SelectionKey> keys = selector.selectedKeys().iterator(); while (keys.hasNext()) { SelectionKey key = keys.next(); keys.remove(); if (!key.isValid()) continue; // WHY Communicator communicator = (Communicator) key.attachment(); if (key.isReadable()) communicator.onReadable(); if (key.isWritable()) communicator.onWritable(); if (key.isAcceptable()) communicator.onAcceptable(); } // Go through the queue and handle each communicator while (!queue.isEmpty()) { Communicator c = queue.poll(); c.onMemo(); } }
public static void main(String[] argv) throws Exception { Pipe[] pipes = new Pipe[PIPES_COUNT]; Pipe pipe = Pipe.open(); Pipe.SinkChannel sink = pipe.sink(); Pipe.SourceChannel source = pipe.source(); Selector sel = Selector.open(); source.configureBlocking(false); source.register(sel, SelectionKey.OP_READ); for (int i = 0; i < PIPES_COUNT; i++) { pipes[i] = Pipe.open(); Pipe.SourceChannel sc = pipes[i].source(); sc.configureBlocking(false); sc.register(sel, SelectionKey.OP_READ); Pipe.SinkChannel sc2 = pipes[i].sink(); sc2.configureBlocking(false); sc2.register(sel, SelectionKey.OP_WRITE); } for (int i = 0; i < LOOPS; i++) { sink.write(ByteBuffer.allocate(BUF_SIZE)); int x = sel.selectNow(); sel.selectedKeys().clear(); source.read(ByteBuffer.allocate(BUF_SIZE)); } for (int i = 0; i < PIPES_COUNT; i++) { pipes[i].sink().close(); pipes[i].source().close(); } pipe.sink().close(); pipe.source().close(); sel.close(); }
private void dispatch() throws IOException { sel.select(); for (Iterator i = sel.selectedKeys().iterator(); i.hasNext(); ) { SelectionKey sk = (SelectionKey) i.next(); i.remove(); Handler h = (Handler) sk.attachment(); h.handle(sk); } }
void processIO() { Iterator<SelectionKey> it = mySelector.selectedKeys().iterator(); while (it.hasNext()) { SelectionKey k = it.next(); it.remove(); if (k.isConnectable()) isConnectable(k); else if (k.isAcceptable()) isAcceptable(k); else { if (k.isWritable()) isWritable(k); if (k.isReadable()) isReadable(k); } } }
public void run() { try { SocketChannel sc = SocketChannel.open(); InetSocketAddress sinaAddr = new InetSocketAddress("sina.com", 80); sc.socket().connect(sinaAddr); // init a selector via helper class selector provider Selector aSel = SelectorProvider.provider().openSelector(); Socket soc = new Socket("host", 80); soc.getChannel().register(aSel, SelectionKey.OP_ACCEPT); // init a channel for server socket. method 1 ServerSocketChannel ssc = ServerSocketChannel.open(); ssc.configureBlocking(true); // method 2, get server socket first, then init its channel ServerSocket ss = new ServerSocket(); ServerSocketChannel ssc2 = ss.getChannel(); // set socket channel as non blocking. ssc.configureBlocking(false); InetSocketAddress isa = new InetSocketAddress("localhost", 9999); ssc.socket().bind(isa); SelectionKey acceptKey = ssc.register(aSel, SelectionKey.OP_ACCEPT); int keysAdded = 0; while ((keysAdded = aSel.select()) > 0) { Set readyKeys = aSel.selectedKeys(); Iterator i = readyKeys.iterator(); while (i.hasNext()) { SelectionKey sk = (SelectionKey) i.next(); i.remove(); ServerSocketChannel n = (ServerSocketChannel) sk.channel(); // now we got a new socket and its channel after accept in server Socket s = n.accept().socket(); SocketChannel socketChannel = s.getChannel(); socketChannel.register(aSel, SelectionKey.OP_READ); } } } catch (Exception e) { } }
public void processSelectedKeys() throws IOException { // 处理连接就绪事件 for (Iterator it = selector.selectedKeys().iterator(); it.hasNext(); ) { SelectionKey selectionKey = (SelectionKey) it.next(); it.remove(); Target target = (Target) selectionKey.attachment(); SocketChannel socketChannel = (SocketChannel) selectionKey.channel(); try { if (socketChannel.finishConnect()) { selectionKey.cancel(); target.connectFinish = System.currentTimeMillis(); socketChannel.close(); addFinishedTarget(target); } } catch (IOException x) { socketChannel.close(); target.failure = x; addFinishedTarget(target); } } }
void processSelectedKeys() throws IOException { for (Iterator i = sel.selectedKeys().iterator(); i.hasNext(); ) { SelectionKey sk = (SelectionKey) i.next(); i.remove(); Target t = (Target) sk.attachment(); SocketChannel sc = (SocketChannel) sk.channel(); try { if (sc.finishConnect()) { sk.cancel(); t.connectFinish = System.currentTimeMillis(); sc.close(); printer.add(t); } } catch (IOException x) { sc.close(); t.failure = x; printer.add(t); } } }
private void go() throws IOException { // Create a new selector Selector selector = Selector.open(); // Open a listener on each port, and register each one // with the selector for (int i = 0; i < ports.length; ++i) { ServerSocketChannel ssc = ServerSocketChannel.open(); ssc.configureBlocking(false); ServerSocket ss = ssc.socket(); InetSocketAddress address = new InetSocketAddress(ports[i]); ss.bind(address); SelectionKey key = ssc.register(selector, SelectionKey.OP_ACCEPT); System.out.println("Going to listen on " + ports[i]); } while (true) { int num = selector.select(); Set selectedKeys = selector.selectedKeys(); Iterator it = selectedKeys.iterator(); while (it.hasNext()) { SelectionKey key = (SelectionKey) it.next(); if ((key.readyOps() & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT) { // Accept the new connection ServerSocketChannel ssc = (ServerSocketChannel) key.channel(); SocketChannel sc = ssc.accept(); sc.configureBlocking(false); // Add the new connection to the selector SelectionKey newKey = sc.register(selector, SelectionKey.OP_READ); it.remove(); System.out.println("Got connection from " + sc); } else if ((key.readyOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ) { // Read the data SocketChannel sc = (SocketChannel) key.channel(); // Echo data int bytesEchoed = 0; while (true) { echoBuffer.clear(); int r = sc.read(echoBuffer); if (r <= 0) { break; } echoBuffer.flip(); sc.write(echoBuffer); bytesEchoed += r; } System.out.println("Echoed " + bytesEchoed + " from " + sc); it.remove(); } } // System.out.println( "going to clear" ); // selectedKeys.clear(); // System.out.println( "cleared" ); } }
public void run() { // Here's where everything happens. The select method will // return when any operations registered above have occurred, the // thread has been interrupted, etc. try { while (!stop) { try { if (selector.select() > 0) { if (stop) { break; } // Someone is ready for I/O, get the ready keys Set readyKeys = selector.selectedKeys(); Iterator it = readyKeys.iterator(); // Walk through the ready keys collection and process date requests. while (it.hasNext()) { SelectionKey sk = (SelectionKey) it.next(); it.remove(); SocketChannel readChannel = null; TcpAddress incomingAddress = null; if (sk.isAcceptable()) { // The key indexes into the selector so you // can retrieve the socket that's ready for I/O ServerSocketChannel nextReady = (ServerSocketChannel) sk.channel(); // Accept the date request and send back the date string Socket s = nextReady.accept().socket(); readChannel = s.getChannel(); readChannel.configureBlocking(false); readChannel.register(selector, SelectionKey.OP_READ); incomingAddress = new TcpAddress(s.getInetAddress(), s.getPort()); SocketEntry entry = new SocketEntry(incomingAddress, s); sockets.put(incomingAddress, entry); timeoutSocket(entry); TransportStateEvent e = new TransportStateEvent( DefaultTcpTransportMapping.this, incomingAddress, TransportStateEvent.STATE_CONNECTED, null); fireConnectionStateChanged(e); } else if (sk.isReadable()) { readChannel = (SocketChannel) sk.channel(); incomingAddress = new TcpAddress( readChannel.socket().getInetAddress(), readChannel.socket().getPort()); } else if (sk.isWritable()) { try { SocketEntry entry = (SocketEntry) sk.attachment(); SocketChannel sc = (SocketChannel) sk.channel(); if (entry != null) { writeMessage(entry, sc); } } catch (IOException iox) { if (logger.isDebugEnabled()) { iox.printStackTrace(); } logger.warn(iox); TransportStateEvent e = new TransportStateEvent( DefaultTcpTransportMapping.this, incomingAddress, TransportStateEvent.STATE_DISCONNECTED_REMOTELY, iox); fireConnectionStateChanged(e); sk.cancel(); } } else if (sk.isConnectable()) { try { SocketEntry entry = (SocketEntry) sk.attachment(); SocketChannel sc = (SocketChannel) sk.channel(); if ((!sc.isConnected()) && (sc.finishConnect())) { sc.configureBlocking(false); logger.debug("Connected to " + entry.getPeerAddress()); // make sure conncetion is closed if not used for timeout // micro seconds timeoutSocket(entry); sc.register(selector, SelectionKey.OP_WRITE, entry); } TransportStateEvent e = new TransportStateEvent( DefaultTcpTransportMapping.this, incomingAddress, TransportStateEvent.STATE_CONNECTED, null); fireConnectionStateChanged(e); } catch (IOException iox) { if (logger.isDebugEnabled()) { iox.printStackTrace(); } logger.warn(iox); sk.cancel(); } } if (readChannel != null) { try { readMessage(sk, readChannel, incomingAddress); } catch (IOException iox) { // IO exception -> channel closed remotely if (logger.isDebugEnabled()) { iox.printStackTrace(); } logger.warn(iox); sk.cancel(); readChannel.close(); TransportStateEvent e = new TransportStateEvent( DefaultTcpTransportMapping.this, incomingAddress, TransportStateEvent.STATE_DISCONNECTED_REMOTELY, iox); fireConnectionStateChanged(e); } } } } } catch (NullPointerException npex) { // There seems to happen a NullPointerException within the select() npex.printStackTrace(); logger.warn("NullPointerException within select()?"); } processPending(); } if (ssc != null) { ssc.close(); } } catch (IOException iox) { logger.error(iox); lastError = iox; } if (!stop) { stop = true; synchronized (DefaultTcpTransportMapping.this) { server = null; } } }
public static void checkClients(List<SocketChannel> anonymousClients) { try { if (selector.selectNow() == 0) { return; } Set<SelectionKey> keys = selector.selectedKeys(); for (SelectionKey key : keys) { if ((key.readyOps() & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT) { SocketChannel clientSocket = serverSocket.accept(); if (clientSocket == null) { System.err.println("Error: can not accept"); continue; } anonymousClients.add(clientSocket); clientSocket.configureBlocking(false); clientSocket.register(selector, SelectionKey.OP_READ); } else if ((key.readyOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ) { SocketChannel clientSocket = (SocketChannel) key.channel(); ByteBuffer bytes = ByteBuffer.allocate(4096); if (clientSocket.read(bytes) != -1) { byte[] message = bytes.array(); switch (message[0]) { case 1: { String nick = MessageUtils.parseMessage(message).first; if (!checkMessage(nick, "", clientSocket)) { continue; } if (clients.containsKey(nick) || nick.length() > 32) { if (nick.length() > 32) { sendMessage( clientSocket, MessageUtils.error("<server>: your nick is too long")); } else { sendMessage( clientSocket, MessageUtils.error("<server>: another user is using this nick")); } sendMessage(clientSocket, MessageUtils.bye()); anonymousClients.remove(clientSocket); Utils.tryClose(clientSocket); } else { System.out.println(nick + " enter this chatroom"); notifyAllClients(nick + " enter this chatroom"); sendMessage( clientSocket, MessageUtils.message("<server>", "Wellcome, your nick is " + nick)); anonymousClients.remove(clientSocket); clients.put(nick, clientSocket); } break; } case 2: { String nick = getNickFromSocket(clientSocket); if (nick == null) { Utils.printErrorAndExit("Error: it could not happen"); } Utils.Pair<String, String> pair = MessageUtils.parseMessage(message); if (!checkMessage(pair.first, pair.second, clientSocket)) { continue; } if (!pair.first.equals(nick)) { System.out.println("Cheater: " + nick); sendMessage(clientSocket, MessageUtils.message("<server>", "do not cheat")); } for (Entry<String, SocketChannel> client : clients.entrySet()) { if (!clientSocket.equals(client.getValue())) { sendMessage(client.getValue(), MessageUtils.message(nick, pair.second)); } } break; } case 3: disconnectClient(clientSocket); break; case 127: { String nick = getNickFromSocket(clientSocket); Utils.Pair<String, String> pair = MessageUtils.parseMessage(message); if (!checkMessage(pair.first, pair.second, clientSocket)) { continue; } if (!pair.first.equals(nick)) { System.out.println("Cheater: " + nick); sendMessage(clientSocket, MessageUtils.message("<server>", "do not cheat")); } System.out.println(nick + ": " + pair.second); break; } default: System.out.println("Bad message from " + getNickFromSocket(clientSocket)); sendMessage(clientSocket, MessageUtils.message("<server>", "bad message")); break; } } else { disconnectClient(clientSocket); } } } keys.clear(); } catch (Exception expt) { expt.printStackTrace(); Utils.printErrorAndExit(expt.getMessage()); } }