class UDPSocket
UDPSocket repräsentiert einen UDP/IP-Socket.
Öffentliche Klassenmethoden
Source
static VALUE
udp_init(int argc, VALUE *argv, VALUE sock)
{
VALUE arg;
int family = AF_INET;
int fd;
if (rb_scan_args(argc, argv, "01", &arg) == 1) {
family = rsock_family_arg(arg);
}
fd = rsock_socket(family, SOCK_DGRAM, 0);
if (fd < 0) {
rb_sys_fail("socket(2) - udp");
}
return rsock_init_sock(sock, fd);
}
Erzeugt ein neues UDPSocket-Objekt.
address_family sollte eine Ganzzahl, ein String oder ein Symbol sein: Socket::AF_INET, “AF_INET”, :INET, etc.
require 'socket' UDPSocket.new #=> #<UDPSocket:fd 3> UDPSocket.new(Socket::AF_INET6) #=> #<UDPSocket:fd 4>
Öffentliche Instanzmethoden
Source
static VALUE
udp_bind(VALUE self, VALUE host, VALUE port)
{
struct udp_arg arg = {.io = self};
arg.res = rsock_addrinfo(host, port, rsock_fd_family(rb_io_descriptor(self)), SOCK_DGRAM, 0, Qnil);
VALUE result = rb_ensure(udp_bind_internal, (VALUE)&arg, rsock_freeaddrinfo, (VALUE)arg.res);
if (!result) {
rsock_sys_fail_host_port("bind(2)", host, port);
}
return INT2FIX(0);
}
Bindet udpsocket an host:port.
u1 = UDPSocket.new u1.bind("127.0.0.1", 4913) u1.send "message-to-self", 0, "127.0.0.1", 4913 p u1.recvfrom(10) #=> ["message-to", ["AF_INET", 4913, "localhost", "127.0.0.1"]]
Source
static VALUE
udp_connect(VALUE self, VALUE host, VALUE port)
{
struct udp_arg arg = {.io = self};
arg.res = rsock_addrinfo(host, port, rsock_fd_family(rb_io_descriptor(self)), SOCK_DGRAM, 0, Qnil);
int result = (int)rb_ensure(udp_connect_internal, (VALUE)&arg, rsock_freeaddrinfo, (VALUE)arg.res);
if (!result) {
rsock_sys_fail_host_port("connect(2)", host, port);
}
return INT2FIX(0);
}
Verbindet udpsocket mit host:port.
Dies ermöglicht das Senden ohne Zieladresse.
u1 = UDPSocket.new u1.bind("127.0.0.1", 4913) u2 = UDPSocket.new u2.connect("127.0.0.1", 4913) u2.send "uuuu", 0 p u1.recvfrom(10) #=> ["uuuu", ["AF_INET", 33230, "localhost", "127.0.0.1"]]
Source
# File ext/socket/lib/socket.rb, line 1735 def recvfrom_nonblock(len, flag = 0, outbuf = nil, exception: true) __recvfrom_nonblock(len, flag, outbuf, exception) end
Empfängt bis zu maxlen Bytes von udpsocket unter Verwendung von recvfrom(2), nachdem O_NONBLOCK für den zugrunde liegenden Dateideskriptor gesetzt wurde. flags ist null oder mehr der MSG_ Optionen. Das erste Element der Ergebnisse, mesg, sind die empfangenen Daten. Das zweite Element, sender_inet_addr, ist ein Array, das die Adresse des Absenders repräsentiert.
Wenn recvfrom(2) 0 zurückgibt, gibt Socket#recv_nonblock nil zurück. In den meisten Fällen bedeutet dies, dass die Verbindung geschlossen wurde, es kann aber auch bedeuten, dass ein leeres Paket empfangen wurde, da die zugrunde liegende API es unmöglich macht, diese beiden Fälle zu unterscheiden.
Parameter
-
maxlen- die Anzahl der Bytes, die vom Socket empfangen werden sollen -
flags- null oder mehr derMSG_-Optionen. -
outbuf- Ziel-String-Puffer -
options- Schlüsselwort-Hash, unterstützt ‘exception: false`
Beispiel
require 'socket' s1 = UDPSocket.new s1.bind("127.0.0.1", 0) s2 = UDPSocket.new s2.bind("127.0.0.1", 0) s2.connect(*s1.addr.values_at(3,1)) s1.connect(*s2.addr.values_at(3,1)) s1.send "aaa", 0 begin # emulate blocking recvfrom p s2.recvfrom_nonblock(10) #=> ["aaa", ["AF_INET", 33302, "localhost.localdomain", "127.0.0.1"]] rescue IO::WaitReadable IO.select([s2]) retry end
Beziehen Sie sich auf Socket#recvfrom für die Ausnahmen, die ausgelöst werden können, wenn der Aufruf von recvfrom_nonblock fehlschlägt.
UDPSocket#recvfrom_nonblock kann jeden Fehler auslösen, der einem recvfrom(2)-Fehler entspricht, einschließlich Errno::EWOULDBLOCK.
Wenn die Ausnahme Errno::EWOULDBLOCK oder Errno::EAGAIN ist, wird sie von IO::WaitReadable erweitert. Daher kann IO::WaitReadable verwendet werden, um die Ausnahmen für Wiederholungsversuche von recvfrom_nonblock abzufangen.
Durch Angabe eines Schlüsselwortarguments exception auf false können Sie angeben, dass recvfrom_nonblock keine IO::WaitReadable-Ausnahme auslösen, sondern das Symbol :wait_readable zurückgeben soll.
Siehe
Source
static VALUE
udp_send(int argc, VALUE *argv, VALUE sock)
{
VALUE flags, host, port;
struct udp_send_arg arg;
VALUE ret;
if (argc == 2 || argc == 3) {
return rsock_bsock_send(argc, argv, sock);
}
rb_scan_args(argc, argv, "4", &arg.sarg.mesg, &flags, &host, &port);
StringValue(arg.sarg.mesg);
GetOpenFile(sock, arg.fptr);
arg.sarg.fd = arg.fptr->fd;
arg.sarg.flags = NUM2INT(flags);
arg.res = rsock_addrinfo(host, port, rsock_fd_family(arg.fptr->fd), SOCK_DGRAM, 0, Qnil);
ret = rb_ensure(udp_send_internal, (VALUE)&arg,
rsock_freeaddrinfo, (VALUE)arg.res);
if (!ret) rsock_sys_fail_host_port("sendto(2)", host, port);
return ret;
}
Sendet mesg über udpsocket.
flags sollte eine bitweise OR-Verknüpfung der Socket::MSG_* Konstanten sein.
u1 = UDPSocket.new u1.bind("127.0.0.1", 4913) u2 = UDPSocket.new u2.send "hi", 0, "127.0.0.1", 4913 mesg, addr = u1.recvfrom(10) u1.send mesg, 0, addr[3], addr[1] p u2.recv(100) #=> "hi"