Class: UDPSocket
- Inherits:
-
IPSocket
- Object
- IO
- BasicSocket
- IPSocket
- UDPSocket
- Defined in:
- udpsocket.c,
udpsocket.c
Overview
UDPSocket represents a UDP/IP socket.
Instance Method Summary collapse
-
#bind(host, port) ⇒ Object
Binds udpsocket to host:port.
-
#connect(host, port) ⇒ 0
Connects udpsocket to host:port.
-
#new([address_family]) ⇒ Object
constructor
Creates a new UDPSocket object.
-
#recvfrom_nonblock(*args) ⇒ Object
Receives up to maxlen bytes from
udpsocket
using recvfrom(2) after O_NONBLOCK is set for the underlying file descriptor. -
#send(*args) ⇒ Object
Sends mesg via udpsocket.
Methods inherited from IPSocket
#addr, getaddress, #peeraddr, #recvfrom
Methods inherited from BasicSocket
#close_read, #close_write, #connect_address, do_not_reverse_lookup, #do_not_reverse_lookup, do_not_reverse_lookup=, #do_not_reverse_lookup=, for_fd, #getpeereid, #getpeername, #getsockname, #getsockopt, #local_address, #recv, #recv_nonblock, #recvmsg, #recvmsg_nonblock, #remote_address, #sendmsg, #sendmsg_nonblock, #setsockopt, #shutdown
Constructor Details
#new([address_family]) ⇒ Object
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'udpsocket.c', line 26
static VALUE
udp_init(int argc, VALUE *argv, VALUE sock)
{
VALUE arg;
int family = AF_INET;
int fd;
rb_secure(3);
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);
}
|
Instance Method Details
#bind(host, port) ⇒ Object
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'udpsocket.c', line 110
static VALUE
udp_bind(VALUE sock, VALUE host, VALUE port)
{
rb_io_t *fptr;
struct rb_addrinfo *res0;
struct addrinfo *res;
rb_secure(3);
res0 = rsock_addrinfo(host, port, SOCK_DGRAM, 0);
GetOpenFile(sock, fptr);
for (res = res0->ai; res; res = res->ai_next) {
if (bind(fptr->fd, res->ai_addr, res->ai_addrlen) < 0) {
continue;
}
rb_freeaddrinfo(res0);
return INT2FIX(0);
}
rb_freeaddrinfo(res0);
rsock_sys_fail_host_port("bind(2)", host, port);
return INT2FIX(0);
}
|
#connect(host, port) ⇒ 0
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'udpsocket.c', line 81
static VALUE
udp_connect(VALUE sock, VALUE host, VALUE port)
{
rb_io_t *fptr;
struct udp_arg arg;
VALUE ret;
rb_secure(3);
arg.res = rsock_addrinfo(host, port, SOCK_DGRAM, 0);
GetOpenFile(sock, fptr);
arg.fd = fptr->fd;
ret = rb_ensure(udp_connect_internal, (VALUE)&arg,
rsock_freeaddrinfo, (VALUE)arg.res);
if (!ret) rsock_sys_fail_host_port("connect(2)", host, port);
return INT2FIX(0);
}
|
#recvfrom_nonblock(maxlen) ⇒ Array #recvfrom_nonblock(maxlen, flags) ⇒ Array
Receives up to maxlen bytes from udpsocket
using recvfrom(2) after O_NONBLOCK is set for the underlying file descriptor. If maxlen is omitted, its default value is 65536. 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 theMSG_
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 begin # emulate blocking recvfrom p s2.recvfrom_nonblock(10) #=> [“aaa”, [“AF_INET”, 33302, “localhost.localdomain”, “127.0.0.1”]] rescue IO::WaitReadable IO.select() 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::AGAIN, it is extended by IO::WaitReadable. So IO::WaitReadable can be used to rescue the exceptions for retrying recvfrom_nonblock.
See
-
Socket#recvfrom
244 245 246 247 248 |
# File 'udpsocket.c', line 244
static VALUE
udp_recvfrom_nonblock(int argc, VALUE *argv, VALUE sock)
{
return rsock_s_recvfrom_nonblock(sock, argc, argv, RECV_IP);
}
|
#send(mesg, flags, host, port) ⇒ Object #send(mesg, flags, sockaddr_to) ⇒ Object #send(mesg, flags) ⇒ Object
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
# File 'udpsocket.c', line 156
static VALUE
udp_send(int argc, VALUE *argv, VALUE sock)
{
VALUE flags, host, port;
rb_io_t *fptr;
int n;
struct rb_addrinfo *res0;
struct addrinfo *res;
struct rsock_send_arg arg;
if (argc == 2 || argc == 3) {
return rsock_bsock_send(argc, argv, sock);
}
rb_scan_args(argc, argv, "4", &arg.mesg, &flags, &host, &port);
StringValue(arg.mesg);
res0 = rsock_addrinfo(host, port, SOCK_DGRAM, 0);
GetOpenFile(sock, fptr);
arg.fd = fptr->fd;
arg.flags = NUM2INT(flags);
for (res = res0->ai; res; res = res->ai_next) {
retry:
arg.to = res->ai_addr;
arg.tolen = res->ai_addrlen;
rsock_maybe_fd_writable(arg.fd);
n = (int)BLOCKING_REGION_FD(rsock_sendto_blocking, &arg);
if (n >= 0) {
rb_freeaddrinfo(res0);
return INT2FIX(n);
}
if (rb_io_wait_writable(fptr->fd)) {
goto retry;
}
}
rb_freeaddrinfo(res0);
rsock_sys_fail_host_port("sendto(2)", host, port);
return INT2FIX(n);
}
|