博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Multicasting in Ruby
阅读量:6072 次
发布时间:2019-06-20

本文共 3669 字,大约阅读时间需要 12 分钟。

最近有一个项目准备用多播来做心跳. 网上转了一篇ruby多播的文章.
原文

Multicasting in Ruby

It’s a bit hard to dig up, but I did figure out how to do UDP packet multicasting in Ruby.

Multicasting

I’ve been playing around with some network peer to peer discovery techniques and wanted to try some of them out in Ruby. The trick to self discovery is the ability to send network packets without knowing the address of the receiver. To do this, you either have to broadcast or multicast.

Because broadcasted packets are received by every device on the local network, it is generally considered good manners to not use broadcasted packets.

Multicasting, on the other hand, is only received by hosts that explicitly express an interest in the multicast address. Although abuse of multicasting is still bad manners, it is a better option than broadcasting.

Sending Multicast Packets

The IP addresses 224.0.0.0 through 239.255.255.255 are reserved for multicast messages. Simply sending a UDP messsage to an address in that range is sufficient.

One minor refinement is to set the TTL (Time To Live) option on the socket. My understanding is that this controls how far the packet is propagated. As polite net-citizens, we don’t want our multicast packets travelling too far abroad, so we set the TTL value to 1 (we need the ugly packing stuff because the value is passed directly to the C level setsockopt() function with no interpretation by Ruby).

So the Ruby code to send a multicast message is:

require 'socket'
MULTICAST_ADDR = "225.4.5.6" 
PORT= 5000
begin
  socket = UDPSocket.open
  socket.setsockopt(Socket::IPPROTO_IP, Socket::IP_TTL, [1].pack('i'))
  socket.send(ARGV.join(' '), 0, MULTICAST_ADDR, PORT)
ensure
  socket.close 
end
Receiving Multicast Messages

Receiving a multicast message is a bit tricker. Since multicast messages are generally ignored unless someone has explicitly registered an interest in a particular address, there is a bit of setup that needs to be done.

Here’s the code for receiving multicast messages:

require 'socket'
require 'ipaddr'
MULTICAST_ADDR = "225.4.5.6" 
PORT = 5000
ip =  IPAddr.new(MULTICAST_ADDR).hton + IPAddr.new("0.0.0.0").hton
sock = UDPSocket.new
sock.setsockopt(Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, ip)
sock.bind(Socket::INADDR_ANY, PORT)
loop do
  msg, info = sock.recvfrom(1024)
  puts "MSG: #{msg} from #{info[2]} (#{info[3]})/#{info[1]} len #{msg.size}" 
end
The tricky part was figuring out the right setsockopt options and values needed to register interest in our multicast address. I had to do a little reading in the Unix man pages on the C level setsockopt() function call. The third option to the C function is a structure that contains two 4-byte IP addresses. The first IP address is the multicast address, and the second IP address is the address of the local host adapter that we wish to use to listen for the multicast. The 0.0.0.0 address means use any of the local network adapters. IPAddr handles parsing the human readable form of the IP address and returns a string of 4 bytes in the order needed by the C level setsockopt() function.

Usage

Save the above code in files named send.rb and rcv.rb. In one console window, type:

ruby rcv.rb
In another console window on the same or different machine (on the same local network), type:

ruby send.rb This is a test.
For more fun, bring up several receive windows and all will receive the messages send by the send script.

I can think of all kinds of fun things to do with this.

Update

I added the Time To Live option on send.

To set TTL for multicast packets you need to use IP_MULTICAST_TTL not IP_TTL. Also, setting IP_MULTICAST_LOOP to 0 will prevent the sender from seeing it's own packets.

转载地址:http://bjsgx.baihongyu.com/

你可能感兴趣的文章
模拟spi如何写
查看>>
configparser配置文件模块
查看>>
POJ 3295:Tautology
查看>>
(转载)浅谈C#中的泛型
查看>>
Robotlegs一个基于puremvc的框架
查看>>
unity射线碰撞检测+LayerMask的使用
查看>>
[转]字符集编码常识
查看>>
【BZOJ1305】【CQOI2009】 dance跳舞
查看>>
Copy 方法 和 ostream 迭代器
查看>>
层中层事件问题
查看>>
用 strcoll 实现中文按拼音排序
查看>>
uwp
查看>>
阿里云
查看>>
随机生成数
查看>>
log4net使用简明教程
查看>>
Python 面向对象
查看>>
pip离线安装python包
查看>>
根据登录用户获取liferay的角色
查看>>
java项目中ehcache缓存最简单用法
查看>>
Web前端性能优化
查看>>