summaryrefslogtreecommitdiff
path: root/ext/socket/lib
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-10-08 15:01:57 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-10-08 15:01:57 +0000
commitabd31dc2ad9e11e71ff512b46a606ccbb207925f (patch)
treea5c3a971f947ecaf6fac007c1fc2e9486d10ba3f /ext/socket/lib
parent866c79e2de4567d71f432652c58b48fe50916f37 (diff)
* ext/socket/lib/socket.rb (Socket.udp_server_recv): extracted from
Socket.udp_server_loop_on. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@25261 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/socket/lib')
-rw-r--r--ext/socket/lib/socket.rb61
1 files changed, 42 insertions, 19 deletions
diff --git a/ext/socket/lib/socket.rb b/ext/socket/lib/socket.rb
index b3b31d8..5dd5ca6 100644
--- a/ext/socket/lib/socket.rb
+++ b/ext/socket/lib/socket.rb
@@ -553,6 +553,46 @@ class Socket
end
# :call-seq:
+ # Socket.udp_server_recv(sockets) {|msg, msg_src| ... }
+ #
+ # Receive UDP/IP packets from the given _sockets_.
+ # For each packet received, the block is called.
+ #
+ # The block receives _msg_ and _msg_src_.
+ # _msg_ is a string which is the payload of the received packet.
+ # _msg_src_ is a Socket::UDPSource object which is used for reply.
+ #
+ # Socket.udp_server_loop can be implemented using this method as follows.
+ #
+ # udp_server_sockets(host, port) {|sockets|
+ # loop {
+ # readable, _, _ = IO.select(sockets)
+ # udp_server_recv(readable) {|msg, msg_src| ... }
+ # }
+ # }
+ #
+ def self.udp_server_recv(sockets)
+ sockets.each {|r|
+ begin
+ msg, sender_addrinfo, rflags, *controls = r.recvmsg_nonblock
+ rescue IO::WaitReadable
+ next
+ end
+ ai = r.local_address
+ if ai.ipv6? and pktinfo = controls.find {|c| c.cmsg_is?(:IPV6, :PKTINFO) }
+ ai = Addrinfo.udp(pktinfo.ipv6_pktinfo_addr.ip_address, ai.ip_port)
+ yield msg, UDPSource.new(sender_addrinfo, ai) {|reply_msg|
+ r.sendmsg reply_msg, 0, sender_addrinfo, pktinfo
+ }
+ else
+ yield msg, UDPSource.new(sender_addrinfo, ai) {|reply_msg|
+ r.send reply_msg, 0, sender_addrinfo
+ }
+ end
+ }
+ end
+
+ # :call-seq:
# Socket.udp_server_loop_on(sockets) {|msg, msg_src| ... }
#
# Run UDP/IP server loop on the given sockets.
@@ -561,27 +601,10 @@ class Socket
#
# It calls the block for each message received.
#
- def self.udp_server_loop_on(sockets) # :yield: msg, msg_src
+ def self.udp_server_loop_on(sockets, &b) # :yield: msg, msg_src
loop {
readable, _, _ = IO.select(sockets)
- readable.each {|r|
- begin
- msg, sender_addrinfo, rflags, *controls = r.recvmsg_nonblock
- rescue IO::WaitReadable
- next
- end
- ai = r.local_address
- if ai.ipv6? and pktinfo = controls.find {|c| c.cmsg_is?(:IPV6, :PKTINFO) }
- ai = Addrinfo.udp(pktinfo.ipv6_pktinfo_addr.ip_address, ai.ip_port)
- yield msg, UDPSource.new(sender_addrinfo, ai) {|reply_msg|
- r.sendmsg reply_msg, 0, sender_addrinfo, pktinfo
- }
- else
- yield msg, UDPSource.new(sender_addrinfo, ai) {|reply_msg|
- r.send reply_msg, 0, sender_addrinfo
- }
- end
- }
+ udp_server_recv(sockets, &b)
}
end