void send(byte[] data) throws IOException { SocketChannel channel = (SocketChannel) key.channel(); verboseLog("TCP write", data); byte[] lengthArray = new byte[2]; lengthArray[0] = (byte) (data.length >>> 8); lengthArray[1] = (byte) (data.length & 0xFF); ByteBuffer[] buffers = new ByteBuffer[2]; buffers[0] = ByteBuffer.wrap(lengthArray); buffers[1] = ByteBuffer.wrap(data); int nsent = 0; key.interestOps(SelectionKey.OP_WRITE); try { while (nsent < data.length + 2) { if (key.isWritable()) { long n = channel.write(buffers); if (n < 0) throw new EOFException(); nsent += (int) n; if (nsent < data.length + 2 && System.currentTimeMillis() > endTime) throw new SocketTimeoutException(); } else blockUntil(key, endTime); } } finally { if (key.isValid()) key.interestOps(0); } }
static void test() throws Exception { ServerSocketChannel ssc = null; SocketChannel sc = null; SocketChannel peer = null; try { ssc = ServerSocketChannel.open().bind(new InetSocketAddress(0)); // loopback connection InetAddress lh = InetAddress.getLocalHost(); sc = SocketChannel.open(new InetSocketAddress(lh, ssc.socket().getLocalPort())); peer = ssc.accept(); // peer sends message so that "sc" will be readable int n = peer.write(ByteBuffer.wrap("Hello".getBytes())); assert n > 0; sc.configureBlocking(false); Selector selector = Selector.open(); SelectionKey key = sc.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE); boolean done = false; int failCount = 0; while (!done) { int nSelected = selector.select(); if (nSelected > 0) { if (nSelected > 1) throw new RuntimeException("More than one channel selected"); Set<SelectionKey> keys = selector.selectedKeys(); Iterator<SelectionKey> iterator = keys.iterator(); while (iterator.hasNext()) { key = iterator.next(); iterator.remove(); if (key.isWritable()) { failCount++; if (failCount > 10) throw new RuntimeException("Test failed"); Thread.sleep(250); } if (key.isReadable()) { done = true; } } } } } finally { if (peer != null) peer.close(); if (sc != null) sc.close(); if (ssc != null) ssc.close(); } }
private void send(SocketChannel sc, ClientInfo ci) throws IOException { int len = ci.outBuf.remaining(); int nBytes = sc.write(ci.outBuf); if (nBytes != len) { // Client not ready to receive data ci.outputPending = true; ci.channel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE); } else { ci.outBuf.clear(); if (ci.outputPending) { ci.outputPending = false; ci.channel.register(selector, SelectionKey.OP_READ); } } }
private void writeMessage(SocketEntry entry, SocketChannel sc) throws IOException { byte[] message = entry.nextMessage(); if (message != null) { ByteBuffer buffer = ByteBuffer.wrap(message); sc.write(buffer); if (logger.isDebugEnabled()) { logger.debug( "Send message with length " + message.length + " to " + entry.getPeerAddress() + ": " + new OctetString(message).toHexString()); } sc.register(selector, SelectionKey.OP_READ); } }
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 static void main(String[] args) { try { System.out.println("CliTest.java"); // create TCP socket channel SocketChannel channel = SocketChannel.open(); System.out.println("CliTest.java: channel created"); channel.connect(new InetSocketAddress("localhost", PORT)); System.out.println("CliTest.java: channel socket connected"); System.out.println(); // create & send a login message byte[] bytes = LoginMessage.getLoginMessage("user1", "password1"); System.out.println("CliTest.java: login message created"); System.out.println(LoginMessage.getMessageString(bytes)); System.out.printf("CliTest.java: login message length in bytes: %d\n", bytes.length); ByteBuffer buf = ByteBuffer.allocate(4096); buf.put(bytes); buf.flip(); // System.out.printf("CliTest.java: buf.remaining before channel.write(): %d\n", // buf.remaining()); int numwritten = channel.write(buf); System.out.printf( "CliTest.java: login mesage written: number of bytes written: %d\n", numwritten); // read reply message buf.clear(); int numread = channel.read(buf); bytes = new byte[numread]; buf.flip(); buf.get(bytes); if (LoginMessage.isLoginSuccessMessage(bytes)) { System.out.printf( "CliTest.java: first message read: Success Message: number of bytes read: %d\n", numread); // get remote port number from success message int port = LoginMessage.getPort(bytes); System.out.printf("Port Number: %d\n", port); byte playerid = LoginMessage.getPlayerId(bytes); System.out.printf("Player id: %d\n", playerid); String mcastString = LoginMessage.getMulticastAddress(bytes); System.out.printf("Multicast Address: %s\n", mcastString); // create datagram channel & connect to rem port DatagramChannel dchannel = DatagramChannel.open(); dchannel.socket().bind(new InetSocketAddress(0)); dchannel.socket().connect(new InetSocketAddress(channel.socket().getInetAddress(), port)); // get localport of datagram socket int localport = dchannel.socket().getLocalPort(); System.out.printf("UDP local port: %d\n", localport); // send success message to send port number to server bytes = LoginMessage.getLoginSuccessMessage(playerid, null, localport); buf.clear(); buf.put(bytes); buf.flip(); channel.write(buf); DeathMessage dm = new DeathMessage((byte) 1, (byte) 1); bytes = dm.getByteMessage(); buf.clear(); buf.put(bytes); buf.flip(); channel.write(buf); } else { System.out.printf( "CliTest.java: first message read: NOT Success Message: number of bytes read: %d\n", numread); } channel.close(); } catch (Exception e) { e.printStackTrace(); } }
/* * Write the src buffer into the socket channel. */ int write(ByteBuffer src) throws IOException { return sc.write(src); }