class Addrinfo
Die Addrinfo-Klasse bildet `struct addrinfo` auf Ruby ab. Diese Struktur identifiziert einen Internet-Host und einen Dienst.
Öffentliche Klassenmethoden
Source
# File ext/socket/lib/socket.rb, line 230 def self.foreach(nodename, service, family=nil, socktype=nil, protocol=nil, flags=nil, timeout: nil, &block) Addrinfo.getaddrinfo(nodename, service, family, socktype, protocol, flags, timeout: timeout).each(&block) end
iteriert über die Liste der Addrinfo-Objekte, die von Addrinfo.getaddrinfo abgerufen wurden.
Addrinfo.foreach(nil, 80) {|x| p x } #=> #<Addrinfo: 127.0.0.1:80 TCP (:80)> # #<Addrinfo: 127.0.0.1:80 UDP (:80)> # #<Addrinfo: [::1]:80 TCP (:80)> # #<Addrinfo: [::1]:80 UDP (:80)>
Source
static VALUE
addrinfo_s_getaddrinfo(int argc, VALUE *argv, VALUE self)
{
VALUE node, service, family, socktype, protocol, flags, opts, timeout;
rb_scan_args(argc, argv, "24:", &node, &service, &family, &socktype,
&protocol, &flags, &opts);
rb_get_kwargs(opts, &id_timeout, 0, 1, &timeout);
if (timeout == Qundef) {
timeout = Qnil;
}
return addrinfo_list_new(node, service, family, socktype, protocol, flags, timeout);
}
gibt eine Liste von addrinfo-Objekten als Array zurück.
Diese Methode konvertiert nodename (Hostnamen) und service (Port) in addrinfo. Da die Konvertierung nicht eindeutig ist, ist das Ergebnis eine Liste von addrinfo-Objekten.
nodename oder service können nil sein, wenn keine Konvertierung beabsichtigt ist.
family, socktype und protocol sind Hinweise für das bevorzugte Protokoll. Wenn das Ergebnis für einen Socket mit SOCK_STREAM verwendet wird, sollte SOCK_STREAM als socktype angegeben werden. Wenn ja, gibt Addrinfo.getaddrinfo eine für SOCK_STREAM geeignete addrinfo-Liste zurück. Wenn sie weggelassen werden oder nil angegeben wird, ist das Ergebnis nicht eingeschränkt.
Ebenso schränkt PF_INET6 als family auf IPv6 ein.
flags sollte eine bitweise OR-Verknüpfung der Socket::AI_???-Konstanten sein, wie unten gezeigt. Beachten Sie, dass die genaue Liste der Konstanten vom Betriebssystem abhängt.
AI_PASSIVE Get address to use with bind() AI_CANONNAME Fill in the canonical name AI_NUMERICHOST Prevent host name resolution AI_NUMERICSERV Prevent service name resolution AI_V4MAPPED Accept IPv4-mapped IPv6 addresses AI_ALL Allow all addresses AI_ADDRCONFIG Accept only if any address is assigned
Beachten Sie, dass socktype angegeben werden sollte, wann immer die Anwendung die Verwendung der Adresse kennt. Einige Plattformen verursachen einen Fehler, wenn socktype weggelassen und servname als Integer angegeben wird, da einige Portnummern, z. B. 512, ohne socktype mehrdeutig sind.
Addrinfo.getaddrinfo("www.kame.net", 80, nil, :STREAM) #=> [#<Addrinfo: 203.178.141.194:80 TCP (www.kame.net)>, # #<Addrinfo: [2001:200:dff:fff1:216:3eff:feb1:44d7]:80 TCP (www.kame.net)>]
Source
static VALUE
addrinfo_s_ip(VALUE self, VALUE host)
{
VALUE ret;
rb_addrinfo_t *rai;
ret = addrinfo_firstonly_new(host, Qnil,
INT2NUM(PF_UNSPEC), INT2FIX(0), INT2FIX(0), INT2FIX(0));
rai = get_addrinfo(ret);
rai->socktype = 0;
rai->protocol = 0;
return ret;
}
gibt ein addrinfo-Objekt für eine IP-Adresse zurück.
Der Port, socktype und das Protokoll des Ergebnisses werden mit Null gefüllt. Daher ist es nicht geeignet, einen Socket zu erstellen.
Addrinfo.ip("localhost") #=> #<Addrinfo: 127.0.0.1 (localhost)>
Source
static VALUE
addrinfo_initialize(int argc, VALUE *argv, VALUE self)
{
rb_addrinfo_t *rai;
VALUE sockaddr_arg, sockaddr_ary, pfamily, socktype, protocol;
int i_pfamily, i_socktype, i_protocol;
struct sockaddr *sockaddr_ptr;
socklen_t sockaddr_len;
VALUE canonname = Qnil, inspectname = Qnil;
if (check_addrinfo(self))
rb_raise(rb_eTypeError, "already initialized socket address");
DATA_PTR(self) = rai = alloc_addrinfo();
rb_scan_args(argc, argv, "13", &sockaddr_arg, &pfamily, &socktype, &protocol);
i_pfamily = NIL_P(pfamily) ? PF_UNSPEC : rsock_family_arg(pfamily);
i_socktype = NIL_P(socktype) ? 0 : rsock_socktype_arg(socktype);
i_protocol = NIL_P(protocol) ? 0 : NUM2INT(protocol);
sockaddr_ary = rb_check_array_type(sockaddr_arg);
if (!NIL_P(sockaddr_ary)) {
VALUE afamily = rb_ary_entry(sockaddr_ary, 0);
int af;
StringValue(afamily);
if (rsock_family_to_int(RSTRING_PTR(afamily), RSTRING_LEN(afamily), &af) == -1)
rb_raise(rb_eSocket, "unknown address family: %s", StringValueCStr(afamily));
switch (af) {
case AF_INET: /* ["AF_INET", 46102, "localhost.localdomain", "127.0.0.1"] */
#ifdef INET6
case AF_INET6: /* ["AF_INET6", 42304, "ip6-localhost", "::1"] */
#endif
{
VALUE service = rb_ary_entry(sockaddr_ary, 1);
VALUE nodename = rb_ary_entry(sockaddr_ary, 2);
VALUE numericnode = rb_ary_entry(sockaddr_ary, 3);
int flags;
service = INT2NUM(NUM2INT(service));
if (!NIL_P(nodename))
StringValue(nodename);
StringValue(numericnode);
flags = AI_NUMERICHOST;
#ifdef AI_NUMERICSERV
flags |= AI_NUMERICSERV;
#endif
init_addrinfo_getaddrinfo(self, rai, numericnode, service,
INT2NUM(i_pfamily ? i_pfamily : af), INT2NUM(i_socktype), INT2NUM(i_protocol),
INT2NUM(flags),
nodename, service);
break;
}
#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN
case AF_UNIX: /* ["AF_UNIX", "/tmp/sock"] */
{
VALUE path = rb_ary_entry(sockaddr_ary, 1);
StringValue(path);
init_unix_addrinfo(self, rai, path, SOCK_STREAM);
break;
}
#endif
default:
rb_raise(rb_eSocket, "unexpected address family");
}
}
else {
StringValue(sockaddr_arg);
sockaddr_ptr = (struct sockaddr *)RSTRING_PTR(sockaddr_arg);
sockaddr_len = RSTRING_SOCKLEN(sockaddr_arg);
init_addrinfo(self, rai, sockaddr_ptr, sockaddr_len,
i_pfamily, i_socktype, i_protocol,
canonname, inspectname);
}
return self;
}
gibt eine neue Instanz von Addrinfo zurück. Die Instanz enthält sockaddr, family, socktype, protocol. sockaddr bedeutet struct sockaddr, das für connect(2) usw. verwendet werden kann. family, socktype und protocol sind ganze Zahlen, die für Argumente von socket(2) verwendet werden.
sockaddr wird als Array oder String angegeben. Das Array sollte mit dem Wert von IPSocket#addr oder UNIXSocket#addr kompatibel sein. Der String sollte eine struct sockaddr sein, wie sie von Socket.sockaddr_in oder Socket.unpack_sockaddr_un generiert wurde.
Beispiele für sockaddr
-
["AF_INET", 46102, "localhost.localdomain", "127.0.0.1"] -
["AF_INET6", 42304, "ip6-localhost", "::1"] -
["AF_UNIX", "/tmp/sock"] -
Socket.sockaddr_in("smtp", "2001:DB8::1") -
Socket.sockaddr_in(80, "172.18.22.42") -
Socket.sockaddr_in(80, "www.ruby-lang.org") -
Socket.sockaddr_un("/tmp/sock")
In einem AF_INET/AF_INET6 sockaddr-Array wird das 4. Element, die numerische IP-Adresse, zur Erstellung der Socket-Adresse in der Addrinfo-Instanz verwendet. Wenn das 3. Element, der textuelle Hostname, nicht nil ist, wird es ebenfalls aufgezeichnet, aber nur für Addrinfo#inspect verwendet.
family wird als ganze Zahl angegeben, um die Protokollfamilie anzugeben, z. B. Socket::PF_INET. Es kann ein Symbol oder ein String sein, der der Konstantenname mit oder ohne PF_-Präfix ist, z. B. :INET, :INET6, :UNIX, „PF_INET“, usw. Wenn weggelassen, wird PF_UNSPEC angenommen.
socktype wird als ganze Zahl angegeben, um den Socket-Typ anzugeben, z. B. Socket::SOCK_STREAM. Es kann ein Symbol oder ein String sein, der der Konstantenname mit oder ohne SOCK_-Präfix ist, z. B. :STREAM, :DGRAM, :RAW, „SOCK_STREAM“, usw. Wenn weggelassen, wird 0 angenommen.
protocol wird als ganze Zahl angegeben, um das Protokoll anzugeben, z. B. Socket::IPPROTO_TCP. Es muss eine ganze Zahl sein, im Gegensatz zu family und socktype. Wenn weggelassen, wird 0 angenommen. Beachten Sie, dass 0 ein sinnvoller Wert für die meisten Protokolle ist, außer für Raw-Sockets.
Source
static VALUE
addrinfo_s_tcp(VALUE self, VALUE host, VALUE port)
{
return addrinfo_firstonly_new(host, port,
INT2NUM(PF_UNSPEC), INT2NUM(SOCK_STREAM), INT2NUM(IPPROTO_TCP), INT2FIX(0));
}
gibt ein addrinfo-Objekt für eine TCP-Adresse zurück.
Addrinfo.tcp("localhost", "smtp") #=> #<Addrinfo: 127.0.0.1:25 TCP (localhost:smtp)>
Source
static VALUE
addrinfo_s_udp(VALUE self, VALUE host, VALUE port)
{
return addrinfo_firstonly_new(host, port,
INT2NUM(PF_UNSPEC), INT2NUM(SOCK_DGRAM), INT2NUM(IPPROTO_UDP), INT2FIX(0));
}
gibt ein addrinfo-Objekt für eine UDP-Adresse zurück.
Addrinfo.udp("localhost", "daytime") #=> #<Addrinfo: 127.0.0.1:13 UDP (localhost:daytime)>
Source
static VALUE
addrinfo_s_unix(int argc, VALUE *argv, VALUE self)
{
VALUE path, vsocktype, addr;
int socktype;
rb_addrinfo_t *rai;
rb_scan_args(argc, argv, "11", &path, &vsocktype);
if (NIL_P(vsocktype))
socktype = SOCK_STREAM;
else
socktype = rsock_socktype_arg(vsocktype);
addr = addrinfo_s_allocate(rb_cAddrinfo);
DATA_PTR(addr) = rai = alloc_addrinfo();
init_unix_addrinfo(self, rai, path, socktype);
return addr;
}
gibt ein addrinfo-Objekt für eine UNIX-Socket-Adresse zurück.
socktype gibt den Socket-Typ an. Wenn es weggelassen wird, wird :STREAM verwendet.
Addrinfo.unix("/tmp/sock") #=> #<Addrinfo: /tmp/sock SOCK_STREAM> Addrinfo.unix("/tmp/sock", :DGRAM) #=> #<Addrinfo: /tmp/sock SOCK_DGRAM>
Öffentliche Instanzmethoden
Source
static VALUE
addrinfo_afamily(VALUE self)
{
rb_addrinfo_t *rai = get_addrinfo(self);
return INT2NUM(ai_get_afamily(rai));
}
gibt die Adressfamilie als ganze Zahl zurück.
Addrinfo.tcp("localhost", 80).afamily == Socket::AF_INET #=> true
Source
# File ext/socket/lib/socket.rb, line 178 def bind sock = Socket.new(self.pfamily, self.socktype, self.protocol) begin sock.ipv6only! if self.ipv6? sock.setsockopt(:SOCKET, :REUSEADDR, 1) sock.bind(self) rescue Exception sock.close raise end if block_given? begin yield sock ensure sock.close end else sock end end
erstellt einen Socket, der an self gebunden ist.
Wenn ein Block gegeben ist, wird er mit dem Socket aufgerufen und der Wert des Blocks zurückgegeben. Ansonsten wird der Socket zurückgegeben.
Addrinfo.udp("0.0.0.0", 9981).bind {|s| s.local_address.connect {|s| s.send "hello", 0 } p s.recv(10) #=> "hello" }
Source
static VALUE
addrinfo_canonname(VALUE self)
{
rb_addrinfo_t *rai = get_addrinfo(self);
return rai->canonname;
}
gibt den kanonischen Namen als String zurück.
nil wird zurückgegeben, wenn kein kanonischer Name vorhanden ist.
Der kanonische Name wird von Addrinfo.getaddrinfo gesetzt, wenn AI_CANONNAME angegeben ist.
list = Addrinfo.getaddrinfo("www.ruby-lang.org", 80, :INET, :STREAM, nil, Socket::AI_CANONNAME) p list[0] #=> #<Addrinfo: 221.186.184.68:80 TCP carbon.ruby-lang.org (www.ruby-lang.org)> p list[0].canonname #=> "carbon.ruby-lang.org"
Source
# File ext/socket/lib/socket.rb, line 140 def connect(timeout: nil, &block) connect_internal(nil, timeout, &block) end
erstellt einen Socket, der mit der Adresse von self verbunden ist.
Das optionale Argument opts sind Optionen, die als Hash dargestellt werden. opts kann folgende Optionen enthalten
- :timeout
-
gibt das Timeout in Sekunden an.
Wenn ein Block gegeben ist, wird er mit dem Socket aufgerufen und der Wert des Blocks zurückgegeben. Ansonsten wird der Socket zurückgegeben.
Addrinfo.tcp("www.ruby-lang.org", 80).connect {|s| s.print "GET / HTTP/1.0\r\nHost: www.ruby-lang.org\r\n\r\n" puts s.read }
Source
# File ext/socket/lib/socket.rb, line 117 def connect_from(*args, timeout: nil, &block) connect_internal(family_addrinfo(*args), timeout, &block) end
erstellt einen Socket, der mit der Adresse von self verbunden ist.
Wenn ein oder mehrere Argumente als local_addr_args gegeben sind, werden sie als lokale Adresse des Sockets verwendet. local_addr_args wird für family_addrinfo verwendet, um die tatsächliche Adresse zu erhalten.
Wenn local_addr_args nicht gegeben ist, ist die lokale Adresse des Sockets nicht gebunden.
Das optionale letzte Argument opts sind Optionen, die als Hash dargestellt werden. opts kann folgende Optionen enthalten
- :timeout
-
gibt das Timeout in Sekunden an.
Wenn ein Block gegeben ist, wird er mit dem Socket aufgerufen und der Wert des Blocks zurückgegeben. Ansonsten wird der Socket zurückgegeben.
Addrinfo.tcp("www.ruby-lang.org", 80).connect_from("0.0.0.0", 4649) {|s| s.print "GET / HTTP/1.0\r\nHost: www.ruby-lang.org\r\n\r\n" puts s.read } # Addrinfo object can be taken for the argument. Addrinfo.tcp("www.ruby-lang.org", 80).connect_from(Addrinfo.tcp("0.0.0.0", 4649)) {|s| s.print "GET / HTTP/1.0\r\nHost: www.ruby-lang.org\r\n\r\n" puts s.read }
Source
# File ext/socket/lib/socket.rb, line 163 def connect_to(*args, timeout: nil, &block) remote_addrinfo = family_addrinfo(*args) remote_addrinfo.connect_internal(self, timeout, &block) end
erstellt einen Socket, der mit remote_addr_args verbunden und an self gebunden ist.
Das optionale letzte Argument opts sind Optionen, die als Hash dargestellt werden. opts kann folgende Optionen enthalten
- :timeout
-
gibt das Timeout in Sekunden an.
Wenn ein Block gegeben ist, wird er mit dem Socket aufgerufen und der Wert des Blocks zurückgegeben. Ansonsten wird der Socket zurückgegeben.
Addrinfo.tcp("0.0.0.0", 4649).connect_to("www.ruby-lang.org", 80) {|s| s.print "GET / HTTP/1.0\r\nHost: www.ruby-lang.org\r\n\r\n" puts s.read }
Source
# File ext/socket/lib/socket.rb, line 21 def family_addrinfo(*args) if args.empty? raise ArgumentError, "no address specified" elsif Addrinfo === args.first raise ArgumentError, "too many arguments" if args.length != 1 addrinfo = args.first if (self.pfamily != addrinfo.pfamily) || (self.socktype != addrinfo.socktype) raise ArgumentError, "Addrinfo type mismatch" end addrinfo elsif self.ip? raise ArgumentError, "IP address needs host and port but #{args.length} arguments given" if args.length != 2 host, port = args Addrinfo.getaddrinfo(host, port, self.pfamily, self.socktype, self.protocol)[0] elsif self.unix? raise ArgumentError, "UNIX socket needs single path argument but #{args.length} arguments given" if args.length != 1 path, = args Addrinfo.unix(path) else raise ArgumentError, "unexpected family" end end
erstellt ein Addrinfo-Objekt aus den Argumenten.
Die Argumente werden ähnlich wie bei self interpretiert.
Addrinfo.tcp("0.0.0.0", 4649).family_addrinfo("www.ruby-lang.org", 80) #=> #<Addrinfo: 221.186.184.68:80 TCP (www.ruby-lang.org:80)> Addrinfo.unix("/tmp/sock").family_addrinfo("/tmp/sock2") #=> #<Addrinfo: /tmp/sock2 SOCK_STREAM>
Source
static VALUE
addrinfo_getnameinfo(int argc, VALUE *argv, VALUE self)
{
rb_addrinfo_t *rai = get_addrinfo(self);
VALUE vflags;
char hbuf[1024], pbuf[1024];
int flags, error;
rb_scan_args(argc, argv, "01", &vflags);
flags = NIL_P(vflags) ? 0 : NUM2INT(vflags);
if (rai->socktype == SOCK_DGRAM)
flags |= NI_DGRAM;
error = rb_getnameinfo(&rai->addr.addr, rai->sockaddr_len,
hbuf, (socklen_t)sizeof(hbuf), pbuf, (socklen_t)sizeof(pbuf),
flags);
if (error) {
rsock_raise_resolution_error("getnameinfo", error);
}
return rb_assoc_new(rb_str_new2(hbuf), rb_str_new2(pbuf));
}
gibt nodename und service als Paar von Strings zurück. Dies konvertiert struct sockaddr in addrinfo in eine textuelle Darstellung.
flags sollte eine bitweise OR-Verknüpfung der Socket::NI_???-Konstanten sein.
Addrinfo.tcp("127.0.0.1", 80).getnameinfo #=> ["localhost", "www"] Addrinfo.tcp("127.0.0.1", 80).getnameinfo(Socket::NI_NUMERICSERV) #=> ["localhost", "80"]
Source
static VALUE
addrinfo_inspect(VALUE self)
{
rb_addrinfo_t *rai = get_addrinfo(self);
int internet_p;
VALUE ret;
ret = rb_sprintf("#<%s: ", rb_obj_classname(self));
inspect_sockaddr(self, ret);
if (rai->pfamily && ai_get_afamily(rai) != rai->pfamily) {
ID id = rsock_intern_protocol_family(rai->pfamily);
if (id)
rb_str_catf(ret, " %s", rb_id2name(id));
else
rb_str_catf(ret, " PF_\?\?\?(%d)", rai->pfamily);
}
internet_p = rai->pfamily == PF_INET;
#ifdef INET6
internet_p = internet_p || rai->pfamily == PF_INET6;
#endif
if (internet_p && rai->socktype == SOCK_STREAM &&
(rai->protocol == 0 || rai->protocol == IPPROTO_TCP)) {
rb_str_cat2(ret, " TCP");
}
else if (internet_p && rai->socktype == SOCK_DGRAM &&
(rai->protocol == 0 || rai->protocol == IPPROTO_UDP)) {
rb_str_cat2(ret, " UDP");
}
else {
if (rai->socktype) {
ID id = rsock_intern_socktype(rai->socktype);
if (id)
rb_str_catf(ret, " %s", rb_id2name(id));
else
rb_str_catf(ret, " SOCK_\?\?\?(%d)", rai->socktype);
}
if (rai->protocol) {
if (internet_p) {
ID id = rsock_intern_ipproto(rai->protocol);
if (id)
rb_str_catf(ret, " %s", rb_id2name(id));
else
goto unknown_protocol;
}
else {
unknown_protocol:
rb_str_catf(ret, " UNKNOWN_PROTOCOL(%d)", rai->protocol);
}
}
}
if (!NIL_P(rai->canonname)) {
VALUE name = rai->canonname;
rb_str_catf(ret, " %s", StringValueCStr(name));
}
if (!NIL_P(rai->inspectname)) {
VALUE name = rai->inspectname;
rb_str_catf(ret, " (%s)", StringValueCStr(name));
}
rb_str_buf_cat2(ret, ">");
return ret;
}
gibt einen String zurück, der addrinfo in menschenlesbarer Form anzeigt.
Addrinfo.tcp("localhost", 80).inspect #=> "#<Addrinfo: 127.0.0.1:80 TCP (localhost)>" Addrinfo.unix("/tmp/sock").inspect #=> "#<Addrinfo: /tmp/sock SOCK_STREAM>"
Source
VALUE
rsock_addrinfo_inspect_sockaddr(VALUE self)
{
return inspect_sockaddr(self, rb_str_new("", 0));
}
gibt einen String zurück, der die sockaddr in addrinfo in menschenlesbarer Form anzeigt.
Addrinfo.tcp("localhost", 80).inspect_sockaddr #=> "127.0.0.1:80" Addrinfo.tcp("ip6-localhost", 80).inspect_sockaddr #=> "[::1]:80" Addrinfo.unix("/tmp/sock").inspect_sockaddr #=> "/tmp/sock"
Source
static VALUE
addrinfo_ip_p(VALUE self)
{
rb_addrinfo_t *rai = get_addrinfo(self);
int family = ai_get_afamily(rai);
return IS_IP_FAMILY(family) ? Qtrue : Qfalse;
}
gibt true zurück, wenn addrinfo eine Internet-Adresse (IPv4/IPv6) ist. Gibt andernfalls false zurück.
Addrinfo.tcp("127.0.0.1", 80).ip? #=> true Addrinfo.tcp("::1", 80).ip? #=> true Addrinfo.unix("/tmp/sock").ip? #=> false
Source
static VALUE
addrinfo_ip_address(VALUE self)
{
rb_addrinfo_t *rai = get_addrinfo(self);
int family = ai_get_afamily(rai);
VALUE vflags;
VALUE ret;
if (!IS_IP_FAMILY(family))
rb_raise(rb_eSocket, "need IPv4 or IPv6 address");
vflags = INT2NUM(NI_NUMERICHOST|NI_NUMERICSERV);
ret = addrinfo_getnameinfo(1, &vflags, self);
return rb_ary_entry(ret, 0);
}
Gibt die IP-Adresse als String zurück.
Addrinfo.tcp("127.0.0.1", 80).ip_address #=> "127.0.0.1" Addrinfo.tcp("::1", 80).ip_address #=> "::1"
Source
static VALUE
addrinfo_ip_port(VALUE self)
{
rb_addrinfo_t *rai = get_addrinfo(self);
int family = ai_get_afamily(rai);
int port;
if (!IS_IP_FAMILY(family)) {
bad_family:
#ifdef AF_INET6
rb_raise(rb_eSocket, "need IPv4 or IPv6 address");
#else
rb_raise(rb_eSocket, "need IPv4 address");
#endif
}
switch (family) {
case AF_INET:
if (rai->sockaddr_len != sizeof(struct sockaddr_in))
rb_raise(rb_eSocket, "unexpected sockaddr size for IPv4");
port = ntohs(rai->addr.in.sin_port);
break;
#ifdef AF_INET6
case AF_INET6:
if (rai->sockaddr_len != sizeof(struct sockaddr_in6))
rb_raise(rb_eSocket, "unexpected sockaddr size for IPv6");
port = ntohs(rai->addr.in6.sin6_port);
break;
#endif
default:
goto bad_family;
}
return INT2NUM(port);
}
Gibt die Portnummer als ganze Zahl zurück.
Addrinfo.tcp("127.0.0.1", 80).ip_port #=> 80 Addrinfo.tcp("::1", 80).ip_port #=> 80
Source
static VALUE
addrinfo_ip_unpack(VALUE self)
{
rb_addrinfo_t *rai = get_addrinfo(self);
int family = ai_get_afamily(rai);
VALUE vflags;
VALUE ret, portstr;
if (!IS_IP_FAMILY(family))
rb_raise(rb_eSocket, "need IPv4 or IPv6 address");
vflags = INT2NUM(NI_NUMERICHOST|NI_NUMERICSERV);
ret = addrinfo_getnameinfo(1, &vflags, self);
portstr = rb_ary_entry(ret, 1);
rb_ary_store(ret, 1, INT2NUM(atoi(StringValueCStr(portstr))));
return ret;
}
Gibt die IP-Adresse und Portnummer als 2-Element-Array zurück.
Addrinfo.tcp("127.0.0.1", 80).ip_unpack #=> ["127.0.0.1", 80] Addrinfo.tcp("::1", 80).ip_unpack #=> ["::1", 80]
Source
static VALUE
addrinfo_ipv4_p(VALUE self)
{
rb_addrinfo_t *rai = get_addrinfo(self);
return ai_get_afamily(rai) == AF_INET ? Qtrue : Qfalse;
}
gibt true zurück, wenn addrinfo eine IPv4-Adresse ist. Gibt andernfalls false zurück.
Addrinfo.tcp("127.0.0.1", 80).ipv4? #=> true Addrinfo.tcp("::1", 80).ipv4? #=> false Addrinfo.unix("/tmp/sock").ipv4? #=> false
Source
static VALUE
addrinfo_ipv4_loopback_p(VALUE self)
{
uint32_t a;
if (!extract_in_addr(self, &a)) return Qfalse;
if ((a & 0xff000000) == 0x7f000000) /* 127.0.0.0/8 */
return Qtrue;
return Qfalse;
}
Gibt true für IPv4-Loopback-Adressen (127.0.0.0/8) zurück. Andernfalls gibt es false zurück.
Source
static VALUE
addrinfo_ipv4_multicast_p(VALUE self)
{
uint32_t a;
if (!extract_in_addr(self, &a)) return Qfalse;
if ((a & 0xf0000000) == 0xe0000000) /* 224.0.0.0/4 */
return Qtrue;
return Qfalse;
}
Gibt true für IPv4-Multicast-Adressen (224.0.0.0/4) zurück. Andernfalls gibt es false zurück.
Source
static VALUE
addrinfo_ipv4_private_p(VALUE self)
{
uint32_t a;
if (!extract_in_addr(self, &a)) return Qfalse;
if ((a & 0xff000000) == 0x0a000000 || /* 10.0.0.0/8 */
(a & 0xfff00000) == 0xac100000 || /* 172.16.0.0/12 */
(a & 0xffff0000) == 0xc0a80000) /* 192.168.0.0/16 */
return Qtrue;
return Qfalse;
}
Gibt true für IPv4-Privatadressen (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) zurück. Andernfalls gibt es false zurück.
Source
static VALUE
addrinfo_ipv6_p(VALUE self)
{
#ifdef AF_INET6
rb_addrinfo_t *rai = get_addrinfo(self);
return ai_get_afamily(rai) == AF_INET6 ? Qtrue : Qfalse;
#else
return Qfalse;
#endif
}
gibt true zurück, wenn addrinfo eine IPv6-Adresse ist. Gibt andernfalls false zurück.
Addrinfo.tcp("127.0.0.1", 80).ipv6? #=> false Addrinfo.tcp("::1", 80).ipv6? #=> true Addrinfo.unix("/tmp/sock").ipv6? #=> false
Source
static VALUE
addrinfo_ipv6_linklocal_p(VALUE self)
{
struct in6_addr *addr = extract_in6_addr(self);
if (addr && IN6_IS_ADDR_LINKLOCAL(addr)) return Qtrue;
return Qfalse;
}
Gibt true für IPv6-Link-Local-Adressen (fe80::/10) zurück. Andernfalls gibt es false zurück.
Source
static VALUE
addrinfo_ipv6_loopback_p(VALUE self)
{
struct in6_addr *addr = extract_in6_addr(self);
if (addr && IN6_IS_ADDR_LOOPBACK(addr)) return Qtrue;
return Qfalse;
}
Gibt true für IPv6-Loopback-Adressen (::1) zurück. Andernfalls gibt es false zurück.
Source
static VALUE
addrinfo_ipv6_mc_global_p(VALUE self)
{
struct in6_addr *addr = extract_in6_addr(self);
if (addr && IN6_IS_ADDR_MC_GLOBAL(addr)) return Qtrue;
return Qfalse;
}
Gibt true für IPv6-Multicast-Adressen mit globalem Geltungsbereich zurück. Andernfalls gibt es false zurück.
Source
static VALUE
addrinfo_ipv6_mc_linklocal_p(VALUE self)
{
struct in6_addr *addr = extract_in6_addr(self);
if (addr && IN6_IS_ADDR_MC_LINKLOCAL(addr)) return Qtrue;
return Qfalse;
}
Gibt true für IPv6-Multicast-Adressen mit Link-Local-Geltungsbereich zurück. Andernfalls gibt es false zurück.
Source
static VALUE
addrinfo_ipv6_mc_nodelocal_p(VALUE self)
{
struct in6_addr *addr = extract_in6_addr(self);
if (addr && IN6_IS_ADDR_MC_NODELOCAL(addr)) return Qtrue;
return Qfalse;
}
Gibt true für IPv6-Multicast-Adressen mit Node-Local-Geltungsbereich zurück. Andernfalls gibt es false zurück.
Source
static VALUE
addrinfo_ipv6_mc_orglocal_p(VALUE self)
{
struct in6_addr *addr = extract_in6_addr(self);
if (addr && IN6_IS_ADDR_MC_ORGLOCAL(addr)) return Qtrue;
return Qfalse;
}
Gibt true für IPv6-Multicast-Adressen mit organisationslokalem Geltungsbereich zurück. Andernfalls gibt es false zurück.
Source
static VALUE
addrinfo_ipv6_mc_sitelocal_p(VALUE self)
{
struct in6_addr *addr = extract_in6_addr(self);
if (addr && IN6_IS_ADDR_MC_SITELOCAL(addr)) return Qtrue;
return Qfalse;
}
Gibt true für IPv6-Multicast-Adressen mit Site-Local-Geltungsbereich zurück. Andernfalls gibt es false zurück.
Source
static VALUE
addrinfo_ipv6_multicast_p(VALUE self)
{
struct in6_addr *addr = extract_in6_addr(self);
if (addr && IN6_IS_ADDR_MULTICAST(addr)) return Qtrue;
return Qfalse;
}
Gibt true für IPv6-Multicast-Adressen (ff00::/8) zurück. Andernfalls gibt es false zurück.
Source
static VALUE
addrinfo_ipv6_sitelocal_p(VALUE self)
{
struct in6_addr *addr = extract_in6_addr(self);
if (addr && IN6_IS_ADDR_SITELOCAL(addr)) return Qtrue;
return Qfalse;
}
Gibt true für IPv6-Site-Local-Adressen (fec0::/10) zurück. Andernfalls gibt es false zurück.
Source
static VALUE
addrinfo_ipv6_to_ipv4(VALUE self)
{
rb_addrinfo_t *rai = get_addrinfo(self);
struct in6_addr *addr;
int family = ai_get_afamily(rai);
if (family != AF_INET6) return Qnil;
addr = &rai->addr.in6.sin6_addr;
if (IN6_IS_ADDR_V4MAPPED(addr) || IN6_IS_ADDR_V4COMPAT(addr)) {
struct sockaddr_in sin4;
INIT_SOCKADDR_IN(&sin4, sizeof(sin4));
memcpy(&sin4.sin_addr, (char*)addr + sizeof(*addr) - sizeof(sin4.sin_addr), sizeof(sin4.sin_addr));
return rsock_addrinfo_new((struct sockaddr *)&sin4, (socklen_t)sizeof(sin4),
PF_INET, rai->socktype, rai->protocol,
rai->canonname, rai->inspectname);
}
else {
return Qnil;
}
}
Gibt die IPv4-Adresse einer IPv4-abgebildeten/kompatiblen IPv6-Adresse zurück. Gibt nil zurück, wenn self keine IPv4-abgebildete/kompatible IPv6-Adresse ist.
Addrinfo.ip("::192.0.2.3").ipv6_to_ipv4 #=> #<Addrinfo: 192.0.2.3> Addrinfo.ip("::ffff:192.0.2.3").ipv6_to_ipv4 #=> #<Addrinfo: 192.0.2.3> Addrinfo.ip("::1").ipv6_to_ipv4 #=> nil Addrinfo.ip("192.0.2.3").ipv6_to_ipv4 #=> nil Addrinfo.unix("/tmp/sock").ipv6_to_ipv4 #=> nil
Source
static VALUE
addrinfo_ipv6_unique_local_p(VALUE self)
{
struct in6_addr *addr = extract_in6_addr(self);
if (addr && IN6_IS_ADDR_UNIQUE_LOCAL(addr)) return Qtrue;
return Qfalse;
}
Gibt true für IPv6-eindeutige lokale Adressen (fc00::/7, RFC4193) zurück. Andernfalls gibt es false zurück.
Source
static VALUE
addrinfo_ipv6_unspecified_p(VALUE self)
{
struct in6_addr *addr = extract_in6_addr(self);
if (addr && IN6_IS_ADDR_UNSPECIFIED(addr)) return Qtrue;
return Qfalse;
}
Gibt true für IPv6-nicht spezifizierte Adressen (::) zurück. Andernfalls gibt es false zurück.
Source
static VALUE
addrinfo_ipv6_v4compat_p(VALUE self)
{
struct in6_addr *addr = extract_in6_addr(self);
if (addr && IN6_IS_ADDR_V4COMPAT(addr)) return Qtrue;
return Qfalse;
}
Gibt true für IPv4-kompatible IPv6-Adressen (::/80) zurück. Andernfalls gibt es false zurück.
Source
static VALUE
addrinfo_ipv6_v4mapped_p(VALUE self)
{
struct in6_addr *addr = extract_in6_addr(self);
if (addr && IN6_IS_ADDR_V4MAPPED(addr)) return Qtrue;
return Qfalse;
}
Gibt true für IPv4-abgebildete IPv6-Adressen (::ffff:0:0/80) zurück. Andernfalls gibt es false zurück.
Source
# File ext/socket/lib/socket.rb, line 200 def listen(backlog=Socket::SOMAXCONN) sock = Socket.new(self.pfamily, self.socktype, self.protocol) begin sock.ipv6only! if self.ipv6? sock.setsockopt(:SOCKET, :REUSEADDR, 1) unless self.pfamily == Socket::PF_UNIX sock.bind(self) sock.listen(backlog) rescue Exception sock.close raise end if block_given? begin yield sock ensure sock.close end else sock end end
erstellt einen lauschenden Socket, der an self gebunden ist.
Source
static VALUE
addrinfo_pfamily(VALUE self)
{
rb_addrinfo_t *rai = get_addrinfo(self);
return INT2NUM(rai->pfamily);
}
gibt die Protokollfamilie als ganze Zahl zurück.
Addrinfo.tcp("localhost", 80).pfamily == Socket::PF_INET #=> true
Source
static VALUE
addrinfo_protocol(VALUE self)
{
rb_addrinfo_t *rai = get_addrinfo(self);
return INT2NUM(rai->protocol);
}
gibt den Socket-Typ als ganze Zahl zurück.
Addrinfo.tcp("localhost", 80).protocol == Socket::IPPROTO_TCP #=> true
Source
static VALUE
addrinfo_socktype(VALUE self)
{
rb_addrinfo_t *rai = get_addrinfo(self);
return INT2NUM(rai->socktype);
}
gibt den Socket-Typ als ganze Zahl zurück.
Addrinfo.tcp("localhost", 80).socktype == Socket::SOCK_STREAM #=> true
gibt die Socket-Adresse als gepackten struct sockaddr-String zurück.
Addrinfo.tcp("localhost", 80).to_sockaddr #=> "\x02\x00\x00P\x7F\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00"
Source
static VALUE
addrinfo_to_sockaddr(VALUE self)
{
rb_addrinfo_t *rai = get_addrinfo(self);
VALUE ret;
ret = rb_str_new((char*)&rai->addr, rai->sockaddr_len);
return ret;
}
gibt die Socket-Adresse als gepackten struct sockaddr-String zurück.
Addrinfo.tcp("localhost", 80).to_sockaddr #=> "\x02\x00\x00P\x7F\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00"
Source
static VALUE
addrinfo_unix_p(VALUE self)
{
rb_addrinfo_t *rai = get_addrinfo(self);
#ifdef AF_UNIX
return ai_get_afamily(rai) == AF_UNIX ? Qtrue : Qfalse;
#else
return Qfalse;
#endif
}
gibt true zurück, wenn addrinfo eine UNIX-Adresse ist. Gibt andernfalls false zurück.
Addrinfo.tcp("127.0.0.1", 80).unix? #=> false Addrinfo.tcp("::1", 80).unix? #=> false Addrinfo.unix("/tmp/sock").unix? #=> true
Source
static VALUE
addrinfo_unix_path(VALUE self)
{
rb_addrinfo_t *rai = get_addrinfo(self);
int family = ai_get_afamily(rai);
struct sockaddr_un *addr;
long n;
if (family != AF_UNIX)
rb_raise(rb_eSocket, "need AF_UNIX address");
addr = &rai->addr.un;
n = rai_unixsocket_len(rai);
if (n < 0)
rb_raise(rb_eSocket, "too short AF_UNIX address: %"PRIuSIZE" bytes given for minimum %"PRIuSIZE" bytes.",
(size_t)rai->sockaddr_len, offsetof(struct sockaddr_un, sun_path));
if ((long)sizeof(addr->sun_path) < n)
rb_raise(rb_eSocket,
"too long AF_UNIX path (%"PRIuSIZE" bytes given but %"PRIuSIZE" bytes max)",
(size_t)n, sizeof(addr->sun_path));
return rb_str_new(addr->sun_path, n);
}
Gibt den Socket-Pfad als String zurück.
Addrinfo.unix("/tmp/sock").unix_path #=> "/tmp/sock"
Geschützte Instanzmethoden
Source
# File ext/socket/lib/socket.rb, line 54 def connect_internal(local_addrinfo, timeout=nil) # :yields: socket sock = Socket.new(self.pfamily, self.socktype, self.protocol) begin sock.ipv6only! if self.ipv6? sock.bind local_addrinfo if local_addrinfo if timeout case sock.connect_nonblock(self, exception: false) when 0 # success or EISCONN, other errors raise break when :wait_writable sock.wait_writable(timeout) or raise Errno::ETIMEDOUT, "user specified timeout for #{self.ip_address}:#{self.ip_port}" end while true else sock.connect(self) end rescue Exception sock.close raise end if block_given? begin yield sock ensure sock.close end else sock end end
erstellt einen neuen Socket, der mit der Adresse von local_addrinfo verbunden ist.
Wenn local_addrinfo nil ist, ist die Adresse des Sockets nicht gebunden.
Das timeout gibt die Sekunden für das Timeout an. Errno::ETIMEDOUT wird ausgelöst, wenn ein Timeout auftritt.
Wenn ein Block gegeben ist, wird der erstellte Socket für jede Adresse übergeben.