類別 IPSocket

IPSocketTCPSocketUDPSocket 的超級類別。

公開類別方法

getaddress(host) → ipaddress 按一下以切換來源

查詢 host 的 IP 位址。

require 'socket'

IPSocket.getaddress("localhost")     #=> "127.0.0.1"
IPSocket.getaddress("ip6-localhost") #=> "::1"
static VALUE
ip_s_getaddress(VALUE obj, VALUE host)
{
    union_sockaddr addr;
    struct rb_addrinfo *res = rsock_addrinfo(host, Qnil, AF_UNSPEC, SOCK_STREAM, 0);
    socklen_t len = res->ai->ai_addrlen;

    /* just take the first one */
    memcpy(&addr, res->ai->ai_addr, len);
    rb_freeaddrinfo(res);

    return rsock_make_ipaddr(&addr.addr, len);
}
別名為:getaddress_orig

私人類別方法

getaddress_orig
別名為:getaddress
valid_v6?(addr) 按一下以切換來源
# File lib/ipaddr.rb, line 753
def valid_v6?(addr)
  case addr
  when IPAddr::RE_IPV6ADDRLIKE_FULL
    if $2
      $~[2,4].all? {|i| i.to_i < 256 }
    else
      true
    end
  when IPAddr::RE_IPV6ADDRLIKE_COMPRESSED
    if $4
      addr.count(':') <= 6 && $~[4,4].all? {|i| i.to_i < 256}
    else
      addr.count(':') <= 7
    end
  else
    false
  end
end

公開實例方法

addr([reverse_lookup]) → [address_family, port, hostname, numeric_address] 按一下以切換來源

傳回本機地址,為包含 address_family、port、hostname 和 numeric_address 的陣列。

如果 reverse_lookuptrue:hostname,則 hostname 會使用反向查詢從 numeric_address 取得。如果為 false:numeric,則 hostname 會與 numeric_address 相同。如果為 nil 或省略,則會遵循 ipsocket.do_not_reverse_lookup。另請參閱 Socket.getaddrinfo

TCPSocket.open("www.ruby-lang.org", 80) {|sock|
  p sock.addr #=> ["AF_INET", 49429, "hal", "192.168.0.128"]
  p sock.addr(true)  #=> ["AF_INET", 49429, "hal", "192.168.0.128"]
  p sock.addr(false) #=> ["AF_INET", 49429, "192.168.0.128", "192.168.0.128"]
  p sock.addr(:hostname)  #=> ["AF_INET", 49429, "hal", "192.168.0.128"]
  p sock.addr(:numeric)   #=> ["AF_INET", 49429, "192.168.0.128", "192.168.0.128"]
}
static VALUE
ip_addr(int argc, VALUE *argv, VALUE sock)
{
    rb_io_t *fptr;
    union_sockaddr addr;
    socklen_t len = (socklen_t)sizeof addr;
    int norevlookup;

    GetOpenFile(sock, fptr);

    if (argc < 1 || !rsock_revlookup_flag(argv[0], &norevlookup))
        norevlookup = fptr->mode & FMODE_NOREVLOOKUP;
    if (getsockname(fptr->fd, &addr.addr, &len) < 0)
        rb_sys_fail("getsockname(2)");
    return rsock_ipaddr(&addr.addr, len, norevlookup);
}
inspect → string 按一下以切換來源

傳回描述此 IPSocket 物件的字串。

static VALUE
ip_inspect(VALUE sock)
{
    VALUE str = rb_call_super(0, 0);
    rb_io_t *fptr = RFILE(sock)->fptr;
    union_sockaddr addr;
    socklen_t len = (socklen_t)sizeof addr;
    ID id;
    if (fptr && fptr->fd >= 0 &&
        getsockname(fptr->fd, &addr.addr, &len) >= 0 &&
        (id = rsock_intern_family(addr.addr.sa_family)) != 0) {
        VALUE family = rb_id2str(id);
        char hbuf[1024], pbuf[1024];
        long slen = RSTRING_LEN(str);
        const char last = (slen > 1 && RSTRING_PTR(str)[slen - 1] == '>') ?
            (--slen, '>') : 0;
        str = rb_str_subseq(str, 0, slen);
        rb_str_cat_cstr(str, ", ");
        rb_str_append(str, family);
        if (!rb_getnameinfo(&addr.addr, len, hbuf, sizeof(hbuf),
                            pbuf, sizeof(pbuf), NI_NUMERICHOST | NI_NUMERICSERV)) {
            rb_str_cat_cstr(str, ", ");
            rb_str_cat_cstr(str, hbuf);
            rb_str_cat_cstr(str, ", ");
            rb_str_cat_cstr(str, pbuf);
        }
        if (last) rb_str_cat(str, &last, 1);
    }
    return str;
}
peeraddr([reverse_lookup]) → [address_family, port, hostname, numeric_address] 按一下以切換來源

傳回遠端地址,為包含 address_family、port、hostname 和 numeric_address 的陣列。針對連線導向的 socket 定義,例如 TCPSocket

如果 reverse_lookuptrue:hostname,則 hostname 會使用反向查詢從 numeric_address 取得。如果為 false:numeric,則 hostname 會與 numeric_address 相同。如果為 nil 或省略,則會遵循 ipsocket.do_not_reverse_lookup。另請參閱 Socket.getaddrinfo

TCPSocket.open("www.ruby-lang.org", 80) {|sock|
  p sock.peeraddr #=> ["AF_INET", 80, "carbon.ruby-lang.org", "221.186.184.68"]
  p sock.peeraddr(true)  #=> ["AF_INET", 80, "carbon.ruby-lang.org", "221.186.184.68"]
  p sock.peeraddr(false) #=> ["AF_INET", 80, "221.186.184.68", "221.186.184.68"]
  p sock.peeraddr(:hostname) #=> ["AF_INET", 80, "carbon.ruby-lang.org", "221.186.184.68"]
  p sock.peeraddr(:numeric)  #=> ["AF_INET", 80, "221.186.184.68", "221.186.184.68"]
}
static VALUE
ip_peeraddr(int argc, VALUE *argv, VALUE sock)
{
    rb_io_t *fptr;
    union_sockaddr addr;
    socklen_t len = (socklen_t)sizeof addr;
    int norevlookup;

    GetOpenFile(sock, fptr);

    if (argc < 1 || !rsock_revlookup_flag(argv[0], &norevlookup))
        norevlookup = fptr->mode & FMODE_NOREVLOOKUP;
    if (getpeername(fptr->fd, &addr.addr, &len) < 0)
        rb_sys_fail("getpeername(2)");
    return rsock_ipaddr(&addr.addr, len, norevlookup);
}
recvfrom(maxlen) → [mesg, ipaddr] 按一下以切換來源
recvfrom(maxlen, flags) → [mesg, ipaddr]

接收訊息,並傳回訊息(為字串)和訊息來自的地址。

maxlen 為要接收的最大位元組數。

flags 應為 Socket::MSG_* 常數的按位元 OR。

ipaddr 與 IPSocket#{peeraddr,addr} 相同。

u1 = UDPSocket.new
u1.bind("127.0.0.1", 4913)
u2 = UDPSocket.new
u2.send "uuuu", 0, "127.0.0.1", 4913
p u1.recvfrom(10) #=> ["uuuu", ["AF_INET", 33230, "localhost", "127.0.0.1"]]
static VALUE
ip_recvfrom(int argc, VALUE *argv, VALUE sock)
{
    return rsock_s_recvfrom(sock, argc, argv, RECV_IP);
}