示例#1
0
  public static int getPortFrom(ThreadContext context, IRubyObject _port) {
    int port;
    if (_port instanceof RubyInteger) {
      port = RubyNumeric.fix2int(_port);
    } else {
      IRubyObject portString = _port.convertToString();
      IRubyObject portInteger = portString.convertToInteger("to_i");
      port = RubyNumeric.fix2int(portInteger);

      if (port <= 0) {
        port =
            RubyNumeric.fix2int(
                RubySocket.getservbyname(
                    context, context.runtime.getObject(), new IRubyObject[] {portString}));
      }
    }

    return port;
  }
示例#2
0
  @JRubyMethod(
      name = "initialize",
      required = 1,
      optional = 1,
      visibility = Visibility.PRIVATE,
      backtrace = true)
  public IRubyObject initialize(ThreadContext context, IRubyObject[] args) {
    IRubyObject hostname = args[0];
    IRubyObject port = args.length > 1 ? args[1] : context.getRuntime().getNil();

    if (hostname.isNil()
        || ((hostname instanceof RubyString) && ((RubyString) hostname).isEmpty())) {
      hostname = context.getRuntime().newString("0.0.0.0");
    } else if (hostname instanceof RubyFixnum) {
      // numeric host, use it for port
      port = hostname;
      hostname = context.getRuntime().newString("0.0.0.0");
    }

    String shost = hostname.convertToString().toString();
    try {
      InetAddress addr = InetAddress.getByName(shost);
      ssc = ServerSocketChannel.open();

      int portInt;
      if (port instanceof RubyInteger) {
        portInt = RubyNumeric.fix2int(port);
      } else {
        IRubyObject portString = port.convertToString();
        IRubyObject portInteger = portString.convertToInteger("to_i");
        portInt = RubyNumeric.fix2int(portInteger);

        if (portInt <= 0) {
          portInt =
              RubyNumeric.fix2int(
                  RubySocket.getservbyname(
                      context, context.getRuntime().getObject(), new IRubyObject[] {portString}));
        }
      }

      socket_address = new InetSocketAddress(addr, portInt);
      ssc.socket().bind(socket_address);
      initSocket(context.getRuntime(), new ChannelDescriptor(ssc, new ModeFlags(ModeFlags.RDWR)));
    } catch (InvalidValueException ex) {
      throw context.getRuntime().newErrnoEINVALError();
    } catch (UnknownHostException e) {
      throw sockerr(context.getRuntime(), "initialize: name or service not known");
    } catch (BindException e) {
      // e.printStackTrace();
      String msg = e.getMessage();
      if (msg == null) {
        msg = "bind";
      } else {
        msg = "bind - " + msg;
      }

      // This is ugly, but what can we do, Java provides the same BindingException
      // for both EADDRNOTAVAIL and EADDRINUSE, so we differentiate the errors
      // based on BindException's message.
      if (ADDR_NOT_AVAIL_PATTERN.matcher(msg).find()) {
        throw context.getRuntime().newErrnoEADDRNOTAVAILError(msg);
      } else {
        throw context.getRuntime().newErrnoEADDRINUSEError(msg);
      }
    } catch (SocketException e) {
      String msg = e.getMessage();
      if (msg.indexOf("Permission denied") != -1) {
        throw context.getRuntime().newErrnoEACCESError("bind(2)");
      } else {
        throw sockerr(context.getRuntime(), "initialize: name or service not known");
      }
    } catch (IOException e) {
      throw sockerr(context.getRuntime(), "initialize: name or service not known");
    } catch (IllegalArgumentException iae) {
      throw sockerr(context.getRuntime(), iae.getMessage());
    }

    return this;
  }