static VALUE udp_init(argc, argv, sock) int argc; VALUE *argv; VALUE sock; { VALUE arg; int socktype = AF_INET; int fd; rb_secure(3); if (rb_scan_args(argc, argv, "01", &arg) == 1) { socktype = NUM2INT(arg); } fd = ruby_socket(socktype, SOCK_DGRAM, 0); if (fd < 0) { rb_sys_fail("socket(2) - udp"); } return init_sock(sock, fd); }
static VALUE udp_bind(sock, host, port) VALUE sock, host, port; { OpenFile *fptr; struct addrinfo *res0, *res; rb_secure(3); res0 = sock_addrinfo(host, port, SOCK_DGRAM, 0); GetOpenFile(sock, fptr); for (res = res0; res; res = res->ai_next) { if (bind(fileno(fptr->f), res->ai_addr, res->ai_addrlen) < 0) { continue; } freeaddrinfo(res0); return INT2FIX(0); } freeaddrinfo(res0); rb_sys_fail("bind(2)"); return INT2FIX(0); }
static VALUE udp_connect(sock, host, port) VALUE sock, host, port; { OpenFile *fptr; struct udp_arg arg; VALUE ret; rb_secure(3); arg.res = sock_addrinfo(host, port, SOCK_DGRAM, 0); GetOpenFile(sock, fptr); arg.fd = fileno(fptr->f); ret = rb_ensure(udp_connect_internal, (VALUE)&arg, RUBY_METHOD_FUNC(freeaddrinfo), (VALUE)arg.res); if (!ret) rb_sys_fail("connect(2)"); return INT2FIX(0); }
Receives up to maxlen bytes from udpsocket
using
recvfrom(2) after O_NONBLOCK is set for the underlying file descriptor.
flags is zero or more of the MSG_
options. The first
element of the results, mesg, is the data received. The second
element, sender_inet_addr, is an array to represent the sender
address.
When recvfrom(2) returns 0, Socket#recvfrom_nonblock returns an empty string as data. It means an empty packet.
maxlen
- the number of bytes to receive from the socket
flags
- zero or more of the MSG_
options
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 IO.select([s2]) p s2.recvfrom_nonblock(10) #=> ["aaa", ["AF_INET", 33302, "localhost.localdomain", "127.0.0.1"]]
Refer to Socket#recvfrom for the exceptions that may be thrown if the call to recvfrom_nonblock fails.
#recvfrom_nonblock may raise any error corresponding to recvfrom(2) failure, including Errno::EAGAIN.
static VALUE udp_recvfrom_nonblock(int argc, VALUE *argv, VALUE sock) { return s_recvfrom_nonblock(sock, argc, argv, RECV_IP); }
static VALUE udp_send(argc, argv, sock) int argc; VALUE *argv; VALUE sock; { VALUE mesg, flags, host, port; OpenFile *fptr; FILE *f; int n; struct addrinfo *res0, *res; if (argc == 2 || argc == 3) { return bsock_send(argc, argv, sock); } rb_secure(4); rb_scan_args(argc, argv, "4", &mesg, &flags, &host, &port); StringValue(mesg); res0 = sock_addrinfo(host, port, SOCK_DGRAM, 0); GetOpenFile(sock, fptr); f = GetWriteFile(fptr); for (res = res0; res; res = res->ai_next) { retry: n = sendto(fileno(f), RSTRING(mesg)->ptr, RSTRING(mesg)->len, NUM2INT(flags), res->ai_addr, res->ai_addrlen); if (n >= 0) { freeaddrinfo(res0); return INT2FIX(n); } if (rb_io_wait_writable(fileno(f))) { goto retry; } } freeaddrinfo(res0); rb_sys_fail("sendto(2)"); return INT2FIX(n); }