🔍

No recent searches

# class UDPSocket

`UDPSocket` represents a UDP/IP socket.

### Public Class Methods

new([address_family]) → socket
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);
    }

Creates a new `UDPSocket` object.

address_family should be an integer, a string or a symbol: Socket::AF_INET, “AF_INET”, :INET, etc.

    require 'socket'

    UDPSocket.new                   #=> #<UDPSocket:fd 3>
    UDPSocket.new(Socket::AF_INET6) #=> #<UDPSocket:fd 4>

### Public Instance Methods

bind(host, port) #→ 0
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);
    }

Binds udpsocket to 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"]]

connect(host, port) → 0
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);
    }

Connects udpsocket to host:port.

This makes possible to send without destination address.

    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"]]

recvfrom_nonblock(maxlen [, flags[, outbuf [, options]]]) → [mesg, sender_inet_addr]
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

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#recv_nonblock` returns nil. In most cases it means the connection was closed, but it may also mean an empty packet was received, as the underlying API makes it impossible to distinguish these two cases.

### Parameters

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

- `flags` - zero or more of the `MSG_` options

- `outbuf` - destination `String` buffer

- `options` - keyword hash, supporting ‘exception: false`

### 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
    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

Refer to `Socket#recvfrom` for the exceptions that may be thrown if the call to recvfrom_nonblock fails.

`UDPSocket#recvfrom_nonblock` may raise any error corresponding to recvfrom(2) failure, including Errno::EWOULDBLOCK.

If the exception is Errno::EWOULDBLOCK or Errno::EAGAIN, it is extended by `IO::WaitReadable`. So `IO::WaitReadable` can be used to rescue the exceptions for retrying recvfrom_nonblock.

By specifying a keyword argument exception to `false`, you can indicate that `recvfrom_nonblock` should not raise an `IO::WaitReadable` exception, but return the symbol `:wait_readable` instead.

### See

- `Socket#recvfrom`

send(mesg, flags, host, port) → numbytes_sent
send(mesg, flags, sockaddr_to) → numbytes_sent
send(mesg, flags) → numbytes_sent
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;
    }

Sends mesg via udpsocket.

flags should be a bitwise OR of Socket::MSG_* constants.

    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"