Example #1
0
  @JRubyMethod(name = "initialize", required = 1, optional = 1, visibility = Visibility.PRIVATE)
  public IRubyObject initialize(ThreadContext context, IRubyObject[] args) {
    Ruby runtime = context.runtime;
    IRubyObject _host = args[0];
    IRubyObject _port = args.length > 1 ? args[1] : context.nil;

    String host;
    if (_host.isNil() || ((_host instanceof RubyString) && ((RubyString) _host).isEmpty())) {
      host = "0.0.0.0";
    } else if (_host instanceof RubyFixnum) {
      // numeric host, use it for port
      _port = _host;
      host = "0.0.0.0";
    } else {
      host = _host.convertToString().toString();
    }

    int port = SocketUtils.getPortFrom(context, _port);

    try {
      InetAddress addr = InetAddress.getByName(host);

      ssc = ServerSocketChannel.open();
      socket_address = new InetSocketAddress(addr, port);

      ssc.socket().bind(socket_address);

      initSocket(runtime, new ChannelDescriptor(ssc, newModeFlags(runtime, ModeFlags.RDWR)));

    } catch (UnknownHostException e) {
      throw SocketUtils.sockerr(runtime, "initialize: name or service not known");

    } catch (BindException e) {
      throw runtime.newErrnoEADDRFromBindException(e);

    } catch (SocketException e) {
      String msg = e.getMessage();

      if (msg.indexOf("Permission denied") != -1) {
        throw runtime.newErrnoEACCESError("bind(2)");
      } else {
        throw SocketUtils.sockerr(runtime, "initialize: name or service not known");
      }

    } catch (IOException e) {
      throw SocketUtils.sockerr(runtime, "initialize: name or service not known");

    } catch (IllegalArgumentException iae) {
      throw SocketUtils.sockerr(runtime, iae.getMessage());
    }

    return this;
  }
Example #2
0
  @JRubyMethod(name = "accept_nonblock")
  public IRubyObject accept_nonblock(ThreadContext context) {
    Ruby runtime = context.runtime;
    RubyTCPSocket socket = new RubyTCPSocket(runtime, runtime.getClass("TCPSocket"));
    Selector selector = null;

    synchronized (ssc.blockingLock()) {
      boolean oldBlocking = ssc.isBlocking();

      try {
        ssc.configureBlocking(false);
        selector = SelectorFactory.openWithRetryFrom(runtime, SelectorProvider.provider());

        boolean ready = context.getThread().select(this, SelectionKey.OP_ACCEPT, 0);

        if (!ready) {
          // no connection immediately accepted, let them try again
          throw runtime.newErrnoEAGAINError("Resource temporarily unavailable");

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

          return socket;
        }

      } catch (IOException e) {
        throw SocketUtils.sockerr(context.runtime, "problem when accepting");

      } finally {
        try {
          if (selector != null) selector.close();
        } catch (Exception e) {
        }
        try {
          ssc.configureBlocking(oldBlocking);
        } catch (IOException ioe) {
        }
      }
    }
  }
  private void doBind(
      ThreadContext context, Channel channel, InetSocketAddress iaddr, int backlog) {
    Ruby runtime = context.runtime;

    try {
      if (channel instanceof ServerSocketChannel) {
        ServerSocket socket = ((ServerSocketChannel) channel).socket();
        socket.bind(iaddr, backlog);
      } else {
        throw runtime.newErrnoENOPROTOOPTError();
      }
    } catch (UnknownHostException e) {
      throw SocketUtils.sockerr(runtime, "bind(2): unknown host");
    } catch (SocketException e) {
      handleSocketException(runtime, e, "bind(2)", iaddr);
    } catch (IOException e) {
      throw sockerr(runtime, "bind(2): name or service not known", e);
    } catch (IllegalArgumentException e) {
      throw sockerr(runtime, e.getMessage(), e);
    }
  }
Example #4
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");
    }
  }
 @JRubyMethod(notImplemented = true)
 public IRubyObject connect(ThreadContext context, IRubyObject arg) {
   throw SocketUtils.sockerr(context.runtime, "server socket cannot connect");
 }