In Files

  • socket/socket.c

UDPSocket

Public Class Methods

new(p1 = v1) click to toggle source
 
               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);
}
            

Public Instance Methods

bind(p1, p2) click to toggle source
 
               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);
}
            
connect(p1, p2) click to toggle source
 
               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);
}
            
recvfrom_nonblock(maxlen) => [mesg, sender_inet_addr] click to toggle source
recvfrom_nonblock(maxlen, flags) => [mesg, sender_inet_addr]

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.

Parameters

  • maxlen - the number of bytes to receive from the socket

  • flags - zero or more of the MSG_ options

Example

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.

See

 
               static VALUE
udp_recvfrom_nonblock(int argc, VALUE *argv, VALUE sock)
{
    return s_recvfrom_nonblock(sock, argc, argv, RECV_IP);
}
            
send(p1, p2, p3, p4) click to toggle source
 
               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);
}
            

Commenting is here to help enhance the documentation. For example, code samples, or clarification of the documentation.

If you have questions about Ruby or the documentation, please post to one of the Ruby mailing lists. You will get better, faster, help that way.

If you wish to post a correction of the docs, please do so, but also file bug report so that it can be corrected for the next release. Thank you.

If you want to help improve the Ruby documentation, please visit Documenting-ruby.org.

blog comments powered by Disqus