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);
}