/* * Resize (if necessary) the inbound data buffer, and then read more * data into the read buffer. */ int read() throws IOException { /* * Allocate more space if less than 5% remains */ resizeRequestBB(requestBBSize / 20); return sc.read(requestBB); }
private byte[] _recv(int length) throws IOException { SocketChannel channel = (SocketChannel) key.channel(); int nrecvd = 0; byte[] data = new byte[length]; ByteBuffer buffer = ByteBuffer.wrap(data); key.interestOps(SelectionKey.OP_READ); try { while (nrecvd < length) { if (key.isReadable()) { long n = channel.read(buffer); if (n < 0) throw new EOFException(); nrecvd += (int) n; if (nrecvd < length && System.currentTimeMillis() > endTime) throw new SocketTimeoutException(); } else blockUntil(key, endTime); } } finally { if (key.isValid()) key.interestOps(0); } return data; }
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(); } }
private void readMessage(SelectionKey sk, SocketChannel readChannel, TcpAddress incomingAddress) throws IOException { // note that socket has been used SocketEntry entry = (SocketEntry) sockets.get(incomingAddress); if (entry != null) { entry.used(); ByteBuffer readBuffer = entry.getReadBuffer(); if (readBuffer != null) { readChannel.read(readBuffer); if (readBuffer.hasRemaining()) { readChannel.register(selector, SelectionKey.OP_READ, entry); } else { dispatchMessage(incomingAddress, readBuffer, readBuffer.capacity()); } return; } } ByteBuffer byteBuffer = ByteBuffer.wrap(buf); byteBuffer.limit(messageLengthDecoder.getMinHeaderLength()); long bytesRead = readChannel.read(byteBuffer); if (logger.isDebugEnabled()) { logger.debug("Reading header " + bytesRead + " bytes from " + incomingAddress); } MessageLength messageLength = new MessageLength(0, Integer.MIN_VALUE); if (bytesRead == messageLengthDecoder.getMinHeaderLength()) { messageLength = messageLengthDecoder.getMessageLength(ByteBuffer.wrap(buf)); if (logger.isDebugEnabled()) { logger.debug("Message length is " + messageLength); } if ((messageLength.getMessageLength() > getMaxInboundMessageSize()) || (messageLength.getMessageLength() <= 0)) { logger.error( "Received message length " + messageLength + " is greater than inboundBufferSize " + getMaxInboundMessageSize()); synchronized (entry) { entry.getSocket().close(); logger.info("Socket to " + entry.getPeerAddress() + " closed due to an error"); } } else { byteBuffer.limit(messageLength.getMessageLength()); bytesRead += readChannel.read(byteBuffer); if (bytesRead == messageLength.getMessageLength()) { dispatchMessage(incomingAddress, byteBuffer, bytesRead); } else { byte[] message = new byte[byteBuffer.limit()]; byteBuffer.flip(); byteBuffer.get(message, 0, byteBuffer.limit() - byteBuffer.remaining()); entry.setReadBuffer(ByteBuffer.wrap(message)); } readChannel.register(selector, SelectionKey.OP_READ, entry); } } else if (bytesRead < 0) { logger.debug("Socket closed remotely"); sk.cancel(); readChannel.close(); TransportStateEvent e = new TransportStateEvent( DefaultTcpTransportMapping.this, incomingAddress, TransportStateEvent.STATE_DISCONNECTED_REMOTELY, null); fireConnectionStateChanged(e); } }