Пример #1
0
  /*
   * Define the server side of the test.
   *
   * If the server prematurely exits, serverReady will be set to true
   * to avoid infinite hangs.
   */
  void doServerSide() throws Exception {
    // create SSLEngine.
    SSLEngine ssle = createSSLEngine(false);

    // Create a server socket channel.
    InetSocketAddress isa = new InetSocketAddress(InetAddress.getLocalHost(), serverPort);
    ServerSocketChannel ssc = ServerSocketChannel.open();
    ssc.socket().bind(isa);
    serverPort = ssc.socket().getLocalPort();

    // Signal Client, we're ready for his connect.
    serverReady = true;

    // Accept a socket channel.
    SocketChannel sc = ssc.accept();

    // Complete connection.
    while (!sc.finishConnect()) {
      // waiting for the connection completed.
    }

    // handshaking
    handshaking(ssle, sc, null);

    // receive application data
    receive(ssle, sc);

    // send out application data
    deliver(ssle, sc);

    // close the socket channel.
    sc.close();
    ssc.close();
  }
Пример #2
0
  /*
   * Define the client side of the test.
   *
   * If the server prematurely exits, serverReady will be set to true
   * to avoid infinite hangs.
   */
  void doClientSide() throws Exception {
    // create SSLEngine.
    SSLEngine ssle = createSSLEngine(true);

    /*
     * Wait for server to get started.
     */
    while (!serverReady) {
      Thread.sleep(50);
    }

    // Create a non-blocking socket channel.
    SocketChannel sc = SocketChannel.open();
    sc.configureBlocking(false);
    InetSocketAddress isa = new InetSocketAddress(InetAddress.getLocalHost(), serverPort);
    sc.connect(isa);

    // Complete connection.
    while (!sc.finishConnect()) {
      // waiting for the connection completed.
    }

    // handshaking
    handshaking(ssle, sc, null);

    // send out application data
    deliver(ssle, sc);

    // receive application data
    receive(ssle, sc);

    // close the socket channel.
    sc.close();
  }
Пример #3
0
    // Process keys that have become selected
    //
    void processSelectedKeys() throws IOException {
      for (Iterator i = sel.selectedKeys().iterator(); i.hasNext(); ) {

        // Retrieve the next key and remove it from the set
        SelectionKey sk = (SelectionKey) i.next();
        i.remove();

        // Retrieve the target and the channel
        Target t = (Target) sk.attachment();
        SocketChannel sc = (SocketChannel) sk.channel();

        // Attempt to complete the connection sequence
        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);
        }
      }
    }
Пример #4
0
    private void processConnect(Context cx) {
      try {
        removeInterest(SelectionKey.OP_CONNECT);
        addInterest(SelectionKey.OP_WRITE);
        clientChannel.finishConnect();
        if (log.isDebugEnabled()) {
          log.debug("Client {} connected", clientChannel);
        }
        sendOnConnectComplete(cx, 0, true, true);

      } catch (ConnectException ce) {
        if (log.isDebugEnabled()) {
          log.debug("Error completing connect: {}", ce);
        }
        setErrno(Constants.ECONNREFUSED);
        sendOnConnectComplete(cx, Constants.ECONNREFUSED, false, false);

      } catch (IOException ioe) {
        if (log.isDebugEnabled()) {
          log.debug("Error completing connect: {}", ioe);
        }
        setErrno(Constants.EIO);
        sendOnConnectComplete(cx, Constants.EIO, false, false);
      }
    }
  // actual connection logic
  private void _connect() throws IOException {
    // Continuous loop that is only supposed to end when "close" is called.

    selector.select();
    Set<SelectionKey> keys = selector.selectedKeys();
    Iterator<SelectionKey> i = keys.iterator();

    while (i.hasNext()) {
      SelectionKey key = i.next();
      i.remove();
      if (key.isConnectable()) {
        if (socketChannel.isConnectionPending()) {
          socketChannel.finishConnect();
        }
        socketChannel.register(selector, SelectionKey.OP_READ);
        _writeHandshake();
      }
      if (key.isReadable()) {
        try {
          _read();
        } catch (NoSuchAlgorithmException nsa) {
          this.onError(nsa);
        }
      }
    }
  }
Пример #6
0
  /**
   * Establish a connection with the server.
   *
   * @return true in case the connection got established. False if not.
   */
  @SuppressWarnings("nls")
  public boolean connect() {
    try {
      final Servers usedServer = IllaClient.getInstance().getUsedServer();

      final String serverAddress;
      final int serverPort;
      if (usedServer == Servers.customserver) {
        serverAddress = IllaClient.getCfg().getString("serverAddress");
        serverPort = IllaClient.getCfg().getInteger("serverPort");
      } else {
        serverAddress = usedServer.getServerHost();
        serverPort = usedServer.getServerPort();
      }

      final InetSocketAddress address = new InetSocketAddress(serverAddress, serverPort);
      socket = SelectorProvider.provider().openSocketChannel();
      socket.configureBlocking(true);
      socket.socket().setPerformancePreferences(0, 2, 1);

      if (!socket.connect(address)) {
        while (socket.isConnectionPending()) {
          socket.finishConnect();
          try {
            Thread.sleep(1);
          } catch (@Nonnull final InterruptedException e) {
            LOGGER.warn("Waiting time for connection finished got interrupted");
          }
        }
      }

      sender = new Sender(outputQueue, socket);
      sender.setUncaughtExceptionHandler(NetCommCrashHandler.getInstance());
      inputThread = new Receiver(inputQueue, socket);
      inputThread.setUncaughtExceptionHandler(NetCommCrashHandler.getInstance());
      messageHandler = new MessageExecutor(inputQueue);
      messageHandler.setUncaughtExceptionHandler(NetCommCrashHandler.getInstance());

      sender.start();
      inputThread.start();
      messageHandler.start();

      keepAliveTimer =
          new Timer(
              INITIAL_DELAY,
              KEEP_ALIVE_DELAY,
              new Runnable() {
                @Override
                public void run() {
                  World.getNet().sendCommand(keepAliveCmd);
                }
              });
      keepAliveTimer.setRepeats(true);
      keepAliveTimer.start();
    } catch (@Nonnull final IOException e) {
      LOGGER.fatal("Connection error");
      return false;
    }
    return true;
  }
    private void doConnect(SelectionKey key) {
      SocketChannel sc = (SocketChannel) key.channel();
      TCConnectionImpl conn = (TCConnectionImpl) key.attachment();

      try {
        if (sc.finishConnect()) {
          sc.register(selector, SelectionKey.OP_READ, conn);
          conn.finishConnect();
        } else {
          String errMsg = "finishConnect() returned false, but no exception thrown";

          if (logger.isInfoEnabled()) {
            logger.info(errMsg);
          }

          conn.fireErrorEvent(new Exception(errMsg), null);
        }
      } catch (IOException ioe) {
        if (logger.isInfoEnabled()) {
          logger.info("IOException attempting to finish socket connection", ioe);
        }

        conn.fireErrorEvent(ioe, null);
      }
    }
Пример #8
0
  // @Override
  public boolean finishConnect() throws IOException {
    if (_socketType == SocketType.Incoming) {
      throw new IOException("Invalid State-Connect called on an Incoming (server) Socket");
    }

    if (_channel == null) {
      throw new IOException("Invalid State - finishConnect called on closed channel");
    }

    try {
      if (_channel.finishConnect()) {

        _channel.socket().setKeepAlive(true);

        // LOG.info(this + "Connected to: " + _address.getAddress().getHostAddress() + ":" +
        // _address.getPort() + " via Interface:" +
        // _channel.socket().getLocalAddress().getHostAddress());

        return true;
      }
    } catch (IOException e) {
      // LOG.error("channel.finishConnect to address:" + _address.getAddress().getHostAddress() +"
      // port: " + _address.getPort() + " threw exception:" + e.toString());
      throw e;
    }
    return false;
  }
Пример #9
0
  /**
   * Test of a large write on a socket to understand what happens when the write is greater than the
   * combined size of the client send buffer and the server receive buffer and the server side of
   * the socket is either not accepted or already shutdown.
   *
   * @throws IOException
   * @throws InterruptedException
   */
  public void testDirectSockets_largeWrite_NotAccepted() throws IOException, InterruptedException {

    final Random r = new Random();

    // Get a socket addresss for an unused port.
    final InetSocketAddress serverAddr = new InetSocketAddress(getPort(0));

    // First our ServerSocket
    final ServerSocket ss = new ServerSocket();
    try {

      // Size of the server socket receive buffer.
      final int receiveBufferSize = ss.getReceiveBufferSize();

      // Allocate buffer twice as large as the receive buffer.
      final byte[] largeBuffer = new byte[receiveBufferSize * 10];

      if (log.isInfoEnabled()) {
        log.info(
            "receiveBufferSize=" + receiveBufferSize + ", largeBufferSize=" + largeBuffer.length);
      }

      // fill buffer with random data.
      r.nextBytes(largeBuffer);

      // bind the ServerSocket to the specified port.
      ss.bind(serverAddr);

      // Now the first Client SocketChannel
      final SocketChannel cs = SocketChannel.open();
      try {
        /*
         * Note: true if connection made. false if connection in
         * progress.
         */
        final boolean immediate = cs.connect(serverAddr);
        if (!immediate) {
          // Did not connect immediately, so finish connect now.
          if (!cs.finishConnect()) {
            fail("Did not connect.");
          }
        }

        /*
         * Attempt to write data. The server socket is not yet accepted.
         * This should hit a timeout.
         */
        assertTimeout(10L, TimeUnit.SECONDS, new WriteBufferTask(cs, ByteBuffer.wrap(largeBuffer)));

        accept(ss);

      } finally {
        cs.close();
      }

    } finally {

      ss.close();
    }
  }
Пример #10
0
  private void handleInput(SelectionKey key) throws IOException {

    if (key != null && key.isValid()) {

      SocketChannel sc = (SocketChannel) key.channel();
      if (key.isConnectable()) {
        if (sc.finishConnect()) {
          sc.register(selector, SelectionKey.OP_READ);
          doWrite(sc);
        } else System.exit(1);
      }

      if (key.isReadable()) {
        ByteBuffer readBuffer = ByteBuffer.allocate(1024);
        int readBytes = sc.read(readBuffer);
        if (readBytes > 0) {
          readBuffer.flip();
          byte[] bytes = new byte[readBuffer.remaining()];
          readBuffer.get(bytes);
          String body = new String(bytes, "UTF-8");
          System.out.println("Now is : " + body);
          this.stop = true;
        } else if (readBytes < 0) {
          key.cancel();
          sc.close();
        } else {

        }
      }
    }
  }
Пример #11
0
 /**
  * ������ѯ�ķ�ʽ����selector���Ƿ�����Ҫ������¼�������У�����д���
  *
  * @throws IOException
  */
 public void listen() {
   // ��ѯ����selector
   while (true) {
     int readyChannels = 0;
     try {
       readyChannels = selector.select();
       if (readyChannels == 0) {
         continue;
       }
     } catch (IOException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
       if (selector != null) {
         try {
           selector.close();
         } catch (IOException e1) {
           // TODO Auto-generated catch block
           e1.printStackTrace();
         }
       }
     }
     // ���selector��ѡ�е���ĵ����
     Iterator ite = this.selector.selectedKeys().iterator();
     while (ite.hasNext()) {
       SelectionKey key = (SelectionKey) ite.next();
       // ɾ����ѡ��key,�Է��ظ�����
       ite.remove();
       // �����¼�����
       if (key.isValid() && key.isConnectable()) {
         SocketChannel channel = (SocketChannel) key.channel();
         // ����������ӣ����������
         if (channel.isConnectionPending()) {
           try {
             channel.finishConnect();
             // ���óɷ�����
             channel.configureBlocking(false);
             // ��������Ը����˷�����ϢŶ
             channel.write(ByteBuffer.wrap(new String("�����˷�����һ����Ϣ").getBytes()));
             // �ںͷ�������ӳɹ�֮��Ϊ�˿��Խ��յ�����˵���Ϣ����Ҫ��ͨ�����ö���Ȩ�ޡ�
             channel.register(this.selector, SelectionKey.OP_READ);
           } catch (IOException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
             if (channel != null) {
               try {
                 channel.close();
               } catch (IOException e1) {
                 // TODO Auto-generated catch block
                 e1.printStackTrace();
               }
             }
           }
         }
       } else if (key.isReadable()) { // ����˿ɶ����¼�
         read(key);
       }
     }
   }
 }
  protected String sendAndReceive(byte[] payload) throws IOException {
    ByteBuffer sbuf = ByteBuffer.wrap(payload);
    ByteBuffer rbuf = ByteBuffer.allocateDirect(256);
    CharsetDecoder rbufDecoder = Charset.forName("UTF-8").newDecoder();
    StringBuilder response = new StringBuilder();

    int ops = SelectionKey.OP_WRITE | SelectionKey.OP_READ;
    if (this.channel.isConnectionPending()) {
      ops = ops | SelectionKey.OP_CONNECT;
    }

    Selector selector = Selector.open();
    try {
      this.channel.register(selector, ops);
      while (true) {
        if (0 < selector.select(Client.POLLS_INTERVAL * 1000)) {
          Iterator keys = selector.selectedKeys().iterator();
          while (keys.hasNext()) {
            SelectionKey key = (SelectionKey) keys.next();
            SocketChannel ch = (SocketChannel) key.channel();
            if (key.isConnectable()) {
              // Just connected
              ch.finishConnect();
            }
            if (key.isReadable() && !sbuf.hasRemaining()) {
              // Receiving the response
              while (0 < ch.read(rbuf)) {
                rbuf.flip();
                response.append(rbufDecoder.decode(rbuf).toString());
              }
              if (2 <= response.length()
                  && response
                      .substring(response.length() - 2, response.length())
                      .equals(SocketClient.TERMINATOR)) {
                response.setLength(response.length() - 2);
                return response.toString();
              } else if (0 == response.length()) {
                throw new IOException("Connection lost");
              }
            }
            if (key.isWritable() && sbuf.hasRemaining()) {
              // Sending the request
              while (0 < ch.write(sbuf) && sbuf.hasRemaining()) {
                //
              }
            }
            keys.remove();
          }
        }
      }
    } catch (java.lang.Exception e) {
      throw new IOException("API communication failed: " + e.toString());
    } finally {
      selector.close();
    }
  }
Пример #13
0
 void connect(SocketAddress addr) throws IOException {
   SocketChannel channel = (SocketChannel) key.channel();
   if (channel.connect(addr)) return;
   key.interestOps(SelectionKey.OP_CONNECT);
   try {
     while (!channel.finishConnect()) {
       if (!key.isConnectable()) blockUntil(key, endTime);
     }
   } finally {
     if (key.isValid()) key.interestOps(0);
   }
 }
Пример #14
0
 /** Called by the selector thread when the connection is ready to be completed. */
 public void handleConnect() {
   try {
     if (!sc.finishConnect()) {
       // Connection failed
       listener.connectionFailed(this, null);
       return;
     }
     // Connection succeeded
     listener.connectionEstablished(this, sc);
   } catch (IOException ex) {
     // Could not connect.
     listener.connectionFailed(this, ex);
   }
 }
Пример #15
0
 /** Should only be invoked by the IOLoop */
 @Override
 public void handleConnect(SelectionKey key) throws IOException {
   logger.debug("handle connect...");
   SocketChannel sc = (SocketChannel) channel;
   if (sc.isConnectionPending()) {
     try {
       sc.finishConnect();
       invokeConnectSuccessfulCallback();
       interestOps &= ~SelectionKey.OP_CONNECT;
       IOLoop.INSTANCE.updateHandler(channel, interestOps |= SelectionKey.OP_READ);
     } catch (ConnectException e) {
       logger.warn("Connect failed: {}", e.getMessage());
       invokeConnectFailureCallback(e);
     }
   }
 }
Пример #16
0
  private void handleInterest(SelectionKey key) {
    SocketChannel channel = (SocketChannel) key.channel();
    ChannelHandler handler = (ChannelHandler) key.attachment();

    synchronized (handler.lock()) {
      try {

        if (key.isValid() && key.isConnectable()) {
          channel.finishConnect();
          handler.getKey().setCachedOps();
          return;
        }

        if (key.isValid() && key.isReadable()) {
          handler.read(channel);
        }

        if (key.isValid() && key.isWritable()) {
          handler.write(channel);
        }

        if (!key.isValid()) {
          channel.close();

          // Remove the link between handler and key
          key.attach(null);
        }

      } catch (CancelledKeyException e) {
        logger.warn("Got cancelled key", e);
      } catch (Exception e) {
        logger.warn("Closing socket due to catched exception", e);

        handler.close();
        key.attach(null);

        try {
          channel.close();
        } catch (IOException t) {
          logger.error("Failed to close channel after force close due to catching an Exception", t);
        }

        key.cancel();
      }
    }
  }
Пример #17
0
 /**
  * Procedure OP_CONNECT of selector
  *
  * @param key Connectable key
  */
 private void connect(SelectionKey key) {
   SocketChannel channel = (SocketChannel) key.channel();
   try {
     channel
         .finishConnect(); // try to finish connection - if 'false' is returned keep 'OP_CONNECT'
                           // registered
     register_connection(channel);
     //            send_message(key, "This is a test message."); //DEBUG
   } catch (IOException e0) {
     try {
       // TODO handle ok?
       if (e0 == null) channel.close();
     } catch (IOException e1) {
       // TODO handle
     }
   }
 }
Пример #18
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();
    }
  }
Пример #19
0
  @Override
  public void open() throws IOException {
    if (channel == null) {
      channel = SocketChannel.open();
      channel.configureBlocking(false);

      if (maxSendBufferSize > 0) {
        channel.setOption(StandardSocketOptions.SO_SNDBUF, maxSendBufferSize);
        final int actualSendBufSize = channel.getOption(StandardSocketOptions.SO_SNDBUF);
        if (actualSendBufSize < maxSendBufferSize) {
          logger.warn(
              "Attempted to set Socket Send Buffer Size to "
                  + maxSendBufferSize
                  + " bytes but could only set to "
                  + actualSendBufSize
                  + "bytes. You may want to "
                  + "consider changing the Operating System's maximum receive buffer");
        }
      }
    }

    if (!channel.isConnected()) {
      final long startTime = System.currentTimeMillis();
      final InetSocketAddress socketAddress =
          new InetSocketAddress(InetAddress.getByName(host), port);

      if (!channel.connect(socketAddress)) {
        while (!channel.finishConnect()) {
          if (System.currentTimeMillis() > startTime + timeout) {
            throw new SocketTimeoutException("Timed out connecting to " + host + ":" + port);
          }

          try {
            Thread.sleep(50L);
          } catch (final InterruptedException e) {
          }
        }
      }

      socketChannelOutput = new SocketChannelOutputStream(channel);
      socketChannelOutput.setTimeout(timeout);
    }
  }
  public static void main(String args[]) throws Exception {

    if ((args.length < 2) || (args.length > 3)) // Test for correct # of args
    throw new IllegalArgumentException("Parameter(s): <Server> <Word> [<Port>]");

    String server = args[0]; // Server name or IP address
    // Convert input String to bytes using the default charset
    byte[] argument = args[1].getBytes();

    int servPort = (args.length == 3) ? Integer.parseInt(args[2]) : 7;

    // Create channel and set to nonblocking
    SocketChannel clntChan = SocketChannel.open();
    clntChan.configureBlocking(false);

    // Initiate connection to server and repeatedly poll until complete
    if (!clntChan.connect(new InetSocketAddress(server, servPort))) {
      while (!clntChan.finishConnect()) {
        System.out.print("."); // Do something else
      }
    }
    ByteBuffer writeBuf = ByteBuffer.wrap(argument);
    ByteBuffer readBuf = ByteBuffer.allocate(argument.length);
    int totalBytesRcvd = 0; // Total bytes received so far
    int bytesRcvd; // Bytes received in last read
    while (totalBytesRcvd < argument.length) {
      if (writeBuf.hasRemaining()) {
        clntChan.write(writeBuf);
      }
      if ((bytesRcvd = clntChan.read(readBuf)) == -1) {
        throw new SocketException("Connection closed prematurely");
      }
      totalBytesRcvd += bytesRcvd;
      System.out.print("."); // Do something else
    }

    System.out.println(
        "Received: "
            + // convert to String per default charset
            new String(readBuf.array(), 0, totalBytesRcvd));
    clntChan.close();
  }
Пример #21
0
 /** 添加新的通道注册 */
 private void addRegister() {
   synchronized (wpool) {
     while (!wpool.isEmpty()) {
       SelectionKey key = (SelectionKey) wpool.remove(0);
       SocketChannel schannel = (SocketChannel) key.channel();
       try {
         schannel.register(selector, SelectionKey.OP_WRITE, key.attachment());
       } catch (Exception e) {
         try {
           schannel.finishConnect();
           schannel.close();
           schannel.socket().close();
           notifier.fireOnClosed((Request) key.attachment());
         } catch (Exception e1) {
         }
         notifier.fireOnError("Error occured in addRegister: " + e.getMessage());
       }
     }
   }
 }
Пример #22
0
  public boolean connect() {
    if (socket != null) return true;

    log.debug("Connecting to " + sa);
    try {
      socket = SocketChannel.open();
      socket.configureBlocking(true);
      socket.connect(sa);
      socket.finishConnect();
      log.debug("Connected");
      return true;
    } catch (IOException ex) {
      log.warn("Connect failed: " + ex.getMessage());
      if (log.isDebugEnabled()) log.debug("Connection failure", ex);

      socket = null;

      return false;
    }
  }
Пример #23
0
  public static void main(String[] args) {
    // TODO Auto-generated method stub
    SocketChannel socketChannel = null;
    ByteBuffer buf = ByteBuffer.allocate(1024 * 1024); // 1M
    boolean isconnected = false;
    try {
      socketChannel = SocketChannel.open();
      isconnected = socketChannel.connect(new InetSocketAddress("192.168.9.119", 8081));
      System.out.println("connecting");
      while (!isconnected && !socketChannel.finishConnect()) {
        System.out.println("waiting");
      }
      if (isconnected) System.out.println("connected");
      else System.out.println("fail");

      File file = new File("/mnt/hgfs/share");

      if (!file.exists()) {
        throw new FileNotFoundException();
      }
      FileInputStream fis = new FileInputStream(file);
      FileChannel fc = fis.getChannel();
      while (buf.hasRemaining()) {
        socketChannel.write(buf);
      }
      System.out.println("finish");
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } finally {
      if (socketChannel != null)
        try {
          socketChannel.close();
        } catch (IOException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
    }
  }
Пример #24
0
  @JRubyMethod(name = "accept")
  public IRubyObject accept(ThreadContext context) {
    Ruby runtime = context.runtime;
    RubyTCPSocket socket = new RubyTCPSocket(runtime, runtime.getClass("TCPSocket"));

    try {
      RubyThread thread = context.getThread();

      while (true) {
        boolean ready = thread.select(this, SelectionKey.OP_ACCEPT);

        if (!ready) {
          // we were woken up without being selected...poll for thread events and go back to sleep
          context.pollThreadEvents();

        } else {
          SocketChannel connected = ssc.accept();
          if (connected == null) continue;

          connected.finishConnect();

          // Force the client socket to be blocking
          synchronized (connected.blockingLock()) {
            connected.configureBlocking(false);
            connected.configureBlocking(true);
          }

          // otherwise one key has been selected (ours) so we get the channel and hand it off
          socket.initSocket(
              runtime, new ChannelDescriptor(connected, newModeFlags(runtime, ModeFlags.RDWR)));

          return socket;
        }
      }

    } catch (IOException e) {
      throw SocketUtils.sockerr(runtime, "problem when accepting");
    }
  }
Пример #25
0
  @JRubyMethod(name = "accept")
  public IRubyObject accept(ThreadContext context) {
    RubyTCPSocket socket =
        new RubyTCPSocket(context.getRuntime(), context.getRuntime().fastGetClass("TCPSocket"));

    try {
      while (true) {
        boolean ready = context.getThread().select(this, SelectionKey.OP_ACCEPT);
        if (!ready) {
          // we were woken up without being selected...poll for thread events and go back to sleep
          context.pollThreadEvents();
        } else {
          try {
            SocketChannel connected = ssc.accept();
            connected.finishConnect();

            //
            // Force the client socket to be blocking
            //
            synchronized (connected.blockingLock()) {
              connected.configureBlocking(false);
              connected.configureBlocking(true);
            }

            // otherwise one key has been selected (ours) so we get the channel and hand it off
            socket.initSocket(
                context.getRuntime(),
                new ChannelDescriptor(connected, new ModeFlags(ModeFlags.RDWR)));
          } catch (InvalidValueException ex) {
            throw context.getRuntime().newErrnoEINVALError();
          }
          return socket;
        }
      }
    } catch (IOException e) {
      throw sockerr(context.getRuntime(), "problem when accepting");
    }
  }
Пример #26
0
  /** called when the selector receives a OP_CONNECT message */
  private void onConnect(@NotNull final SelectionKey key) throws IOException, InterruptedException {

    final SocketChannel channel = (SocketChannel) key.channel();
    final Attached attached = (Attached) key.attachment();

    try {
      if (!channel.finishConnect()) {
        return;
      }
    } catch (SocketException e) {
      quietClose(key, e);
      attached.connector.connect();
      throw e;
    }

    attached.connector.setSuccessfullyConnected();

    if (LOG.isDebugEnabled())
      LOG.debug(
          "successfully connected to {}, local-id={}",
          channel.socket().getInetAddress(),
          localIdentifier);

    channel.configureBlocking(false);
    channel.socket().setTcpNoDelay(true);
    channel.socket().setSoTimeout(0);
    channel.socket().setSoLinger(false, 0);

    attached.entryReader = new TcpSocketChannelEntryReader();
    attached.entryWriter = new TcpSocketChannelEntryWriter();

    key.interestOps(OP_WRITE | OP_READ);

    throttle(channel);

    // register it with the selector and store the ModificationIterator for this key
    attached.entryWriter.identifierToBuffer(localIdentifier);
  }
Пример #27
0
    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);
        }
      }
    }
Пример #28
0
  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);
      }
    }
  }
Пример #29
0
 // Handle IO for a specific selector.  Any IOException will cause a
 // reconnect
 private void handleIO(SelectionKey sk) {
   MemcachedNode qa = (MemcachedNode) sk.attachment();
   try {
     getLogger()
         .debug(
             "Handling IO for:  %s (r=%s, w=%s, c=%s, op=%s)",
             sk, sk.isReadable(), sk.isWritable(), sk.isConnectable(), sk.attachment());
     if (sk.isConnectable()) {
       getLogger().info("Connection state changed for %s", sk);
       final SocketChannel channel = qa.getChannel();
       if (channel.finishConnect()) {
         assert channel.isConnected() : "Not connected.";
         qa.connected();
         addedQueue.offer(qa);
         if (qa.getWbuf().hasRemaining()) {
           handleWrites(sk, qa);
         }
       } else {
         assert !channel.isConnected() : "connected";
       }
     } else {
       if (sk.isReadable()) {
         handleReads(sk, qa);
       }
       if (sk.isWritable()) {
         handleWrites(sk, qa);
       }
     }
   } catch (Exception e) {
     // Various errors occur on Linux that wind up here.  However, any
     // particular error processing an item should simply cause us to
     // reconnect to the server.
     getLogger().info("Reconnecting due to exception on %s", qa, e);
     queueReconnect(qa);
   }
   qa.fixupOps();
 }
Пример #30
0
  private static void testSocketChannel() throws Exception {
    ByteBuffer buf = ByteBuffer.allocateDirect(1024);
    SocketChannel sChannel = SocketChannel.open();
    sChannel.configureBlocking(false);
    sChannel.connect(new InetSocketAddress(HOST, PORT));

    while (!sChannel.finishConnect()) {
      Thread.sleep(100);
      System.out.println("client waiting for connection...");
    }

    buf.clear();
    int numBytesRead = sChannel.read(buf);
    Thread.sleep(100);
    CharBuffer cb = decoder.decode(buf);
    String cbStr = cb.toString();
    System.out.print("cb:" + cbStr);

    if (numBytesRead == -1) {
      sChannel.close();
    } else {
      buf.flip();
    }
  }