@JRubyMethod public IRubyObject setsockopt( ThreadContext context, IRubyObject _level, IRubyObject _opt, IRubyObject val) { Ruby runtime = context.runtime; SocketLevel level = levelFromArg(_level); SocketOption opt = optionFromArg(_opt); try { Channel channel = getOpenChannel(); SocketType socketType = SocketType.forChannel(channel); switch (level) { case SOL_IP: case SOL_SOCKET: case SOL_TCP: case SOL_UDP: if (opt == SocketOption.SO_LINGER) { if (val instanceof RubyBoolean && !val.isTrue()) { socketType.setSoLinger(channel, false, 0); } else { int num = asNumber(val); if (num == -1) { socketType.setSoLinger(channel, false, 0); } else { socketType.setSoLinger(channel, true, num); } } } else { socketType.setSocketOption(channel, opt, asNumber(val)); } break; default: int intLevel = (int) _level.convertToInteger().getLongValue(); int intOpt = (int) _opt.convertToInteger().getLongValue(); if (IPPROTO_TCP.intValue() == intLevel && TCP_NODELAY.intValue() == intOpt) { socketType.setTcpNoDelay(channel, asBoolean(val)); } else if (IPPROTO_IP.intValue() == intLevel) { if (MulticastStateManager.IP_ADD_MEMBERSHIP == intOpt) { joinMulticastGroup(val); } } else { throw runtime.newErrnoENOPROTOOPTError(); } } } catch (BadDescriptorException e) { throw runtime.newErrnoEBADFError(); } catch (IOException e) { throw runtime.newErrnoENOPROTOOPTError(); } return runtime.newFixnum(0); }