public static IRubyObject doAccept(RubySocket sock, ThreadContext context, boolean ex) {
    Ruby runtime = context.runtime;

    Channel channel = sock.getChannel();

    try {
      if (channel instanceof ServerSocketChannel) {
        ServerSocketChannel serverChannel = (ServerSocketChannel) sock.getChannel();

        SocketChannel socket = serverChannel.accept();

        if (socket == null) {
          // This appears to be undocumented in JDK; null as a sentinel value
          // for a nonblocking accept with nothing available. We raise for Ruby.
          // indicates that no connection is available in non-blocking mode
          if (!ex) return runtime.newSymbol("wait_readable");
          throw runtime.newErrnoEAGAINReadableError("accept(2) would block");
        }

        RubySocket rubySocket = new RubySocket(runtime, runtime.getClass("Socket"));
        rubySocket.initFromServer(runtime, sock, socket);

        return runtime.newArray(
            rubySocket,
            new Addrinfo(runtime, runtime.getClass("Addrinfo"), socket.getRemoteAddress()));
      }
      throw runtime.newErrnoENOPROTOOPTError();
    } catch (IllegalBlockingModeException e) {
      // indicates that no connection is available in non-blocking mode
      if (!ex) return runtime.newSymbol("wait_readable");
      throw runtime.newErrnoEAGAINReadableError("accept(2) would block");
    } catch (IOException e) {
      throw sockerr(runtime, e.getLocalizedMessage(), e);
    }
  }
  @Override
  public Void call() throws Exception {
    ServerSocketChannel clientConnection = (ServerSocketChannel) selectionKey.channel();
    SocketChannel channel = clientConnection.accept();

    if (channel != null) {
      channel.configureBlocking(false);

      LOGGER.info(
          String.format("%s accepted client connection from %s", name, channel.getRemoteAddress()));

      try {
        final HttpRequest.HttpRequestWrapper requestWrapper = requestParser.parse(read(channel));

        MethodHandler handler =
            RequestHandlerFactory.newInstance(requestWrapper.getRequestLine().getMethod());
        HttpResponse.HttpResponseWrapper responseWrapper = handler.handle(requestWrapper);
        write(channel, responseWrapper);
      } finally {
        channel.close();
      }

      LOGGER.info(String.format("%s is done.", name));
    }

    return null;
  }
Example #3
0
  /** Handle a read event from a socket specified by the key. */
  private void read(SelectionKey key) throws IOException {
    SocketChannel socketChannel = (SocketChannel) key.channel();
    SocketAddress remoteAdr = socketChannel.socket().getRemoteSocketAddress();

    // Clear out our read buffer so it's ready for new data
    readBuffer.clear();

    // Attempt to read off the channel
    int numRead;
    try {
      numRead = socketChannel.read(readBuffer);
    } catch (IOException e) {
      // The remote forcibly closed the connection, cancel
      // the selection key and close the channel.
      key.cancel();
      socketChannel.close();
      clients.remove(remoteAdr);
      pendingWriteData.remove(socketChannel);
      logger.fine(
          "Connection forcibly closed("
              + remoteAdr
              + ")! Remaining connections: "
              + clients.size());
      throw new IOException("Remote forcibly closed the connection");
    }

    if (numRead == -1) {
      // Remote entity shut the socket down cleanly. Do the
      // same from our end and cancel the channel.
      key.channel().close();
      key.cancel();
      clients.remove(remoteAdr);
      pendingWriteData.remove(socketChannel);
      logger.fine("Connection Closed(" + remoteAdr + ")! Remaining connections: " + clients.size());
      throw new IOException("Remote closed the connection");
    }

    // Make a correctly sized copy of the data before handing it to the client
    // byte[] rspByteData = new byte[numRead];
    // System.arraycopy(readBuffer.array(), 0, rspByteData, 0, numRead);

    try {
      Object rspData = Converter.toObject(readBuffer.array());

      // Hand the data off to our worker thread
      if (worker != null) {
        logger.finer("Handling incoming message...");
        worker.processData(this, socketChannel.getRemoteAddress(), rspData);
      } else {
        logger.fine("No worker set, message unhandled!");
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
Example #4
0
  private void write(SelectionKey key) throws IOException {
    SocketChannel socketChannel = (SocketChannel) key.channel();

    // System.out.println("outsocketaddress:                             :
    // "+socketChannel.getRemoteAddress());
    outgoingdata(socketChannel.getRemoteAddress().toString(), socketChannel, TcpTxTunnel);

    /*    ByteBuffer dummyResponse = ByteBuffer.wrap("ok".getBytes("UTF-8"));
    socketChannel.write(dummyResponse);
    if (dummyResponse.remaining() > 0) {
        System.err.print("Filled UP");
    }*/

    key.interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
  }
Example #5
0
  /** Finnish an ongoing remote connection establishment procedure */
  private void establishConnection(SelectionKey key) {
    SocketChannel socketChannel = (SocketChannel) key.channel();

    try {
      // Finalize/Finish the connection.
      socketChannel.finishConnect();

      // Register an interest in writing on this channel
      key.interestOps(SelectionKey.OP_WRITE);

      registerSocketChannel(socketChannel);
      logger.fine("Connection established(" + socketChannel.getRemoteAddress() + ")");
    } catch (IOException e) {
      // Cancel the channel's registration with our selector
      e.printStackTrace();
      key.cancel();
    }
  }
Example #6
0
  /** Handle an accept event from a remote host. Channel can only be a server socket. */
  private void accept(SelectionKey key) throws IOException {
    // For an accept to be pending the channel must be a server socket channel.
    ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();

    // Accept the connection and make it non-blocking
    SocketChannel socketChannel = serverSocketChannel.accept();
    socketChannel.socket().setReuseAddress(true);
    socketChannel.configureBlocking(false);

    // Register the new SocketChannel with our Selector, indicating
    // we'd like to be notified when there's data waiting to be read
    socketChannel.register(selector, SelectionKey.OP_READ);

    // adds the client to the clients list
    registerSocketChannel(socketChannel);
    logger.fine(
        "New Connection(" + socketChannel.getRemoteAddress() + ")!!! Count: " + clients.size());
  }
Example #7
0
  private void processSelectedKeys() {
    for (SelectionKey key : selector.selectedKeys()) {
      try {
        if (!key.isValid()) continue;

        if (key.isAcceptable()) {
          SocketChannel acceptedChannel = serverChannel.accept();

          if (acceptedChannel == null) continue;

          acceptedChannel.configureBlocking(false);
          SelectionKey readKey = acceptedChannel.register(selector, SelectionKey.OP_READ);
          MainServer.clientMap.put(readKey, new ClientSession(readKey, acceptedChannel));

          LOG.info(
              "New client ip="
                  + acceptedChannel.getRemoteAddress()
                  + ", total clients="
                  + MainServer.clientMap.size());
        } else if (key.isReadable()) {
          ClientSession sesh = MainServer.getClientMap().get(key);

          if (sesh == null) continue;

          reader.read(sesh);
        } else if (key.isWritable()) {
          ClientSession sesh = MainServer.getClientMap().get(key);

          if (sesh == null) continue;

          sender.send(sesh);
        }

      } catch (Throwable t) {
        LOG.severe("NetServerThread exception: " + t.getMessage());
      }
    }
  }
Example #8
0
  private void read(SelectionKey key) throws IOException {
    SocketChannel socketChannel = (SocketChannel) key.channel();

    // Clear out our read buffer so it's ready for new data
    readBuffer.clear();

    // Attempt to read off the channel
    int numRead;
    try {
      numRead = socketChannel.read(readBuffer);
    } catch (IOException e) {
      key.cancel();
      socketChannel.close();

      System.out.println("Forceful shutdown");
      return;
    }

    if (numRead == -1) {
      System.out.println("Graceful shutdown");
      key.channel().close();
      key.cancel();

      return;
    }
    // System.out.println("TEST: "+socketChannel.getRemoteAddress()+ "DATA: "+
    // readBuffer.toString());
    incomingdata(socketChannel.getRemoteAddress().toString(), readBuffer, TcpRxTunnel);

    socketChannel.register(selector, SelectionKey.OP_WRITE);

    numMessages++;
    if (numMessages % 100000 == 0) {
      long elapsed = System.currentTimeMillis() - loopTime;
      loopTime = System.currentTimeMillis();
      System.out.println(elapsed);
    }
  }
 @Override
 public SocketAddress getRemoteAddress() throws IOException {
   return socketChannel.getRemoteAddress();
 }