예제 #1
0
 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);
   }
 }
예제 #2
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();
    }
  }
예제 #3
0
 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);
   }
 }
예제 #5
0
  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" );
    }
  }
예제 #6
0
  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();
    }
  }
예제 #7
0
 /*
  * Write the src buffer into the socket channel.
  */
 int write(ByteBuffer src) throws IOException {
   return sc.write(src);
 }