diff options
author | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2009-10-08 15:01:57 +0000 |
---|---|---|
committer | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2009-10-08 15:01:57 +0000 |
commit | abd31dc2ad9e11e71ff512b46a606ccbb207925f (patch) | |
tree | a5c3a971f947ecaf6fac007c1fc2e9486d10ba3f /ext/socket/lib/socket.rb | |
parent | 866c79e2de4567d71f432652c58b48fe50916f37 (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/socket.rb')
-rw-r--r-- | ext/socket/lib/socket.rb | 61 |
1 files changed, 42 insertions, 19 deletions
diff --git a/ext/socket/lib/socket.rb b/ext/socket/lib/socket.rb index b3b31d87f7..5dd5ca651c 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 |