ruby - 在 Wireshark 中看到多播数据包,但用户程序未收到(Windows 和 Linux)

标签 ruby linux networking multicast

我正在尝试使用来自 Ruby 程序的多播来检测网络连接设备。我从官方检测程序嗅探了网络流量,发现计算机向 225.0.0.37:12345 发送了一个数据包,设备在 225.0.0.38:12346 响应。该设备连接到由 Netgear 交换机、Windows 计算机和 Linux 计算机组成的本地网络。我已让我的程序发送与官方程序相同的数据包。

我遇到的问题是我的程序和官方检测程序都没有收到响应。使用 Wireshark 我可以清楚地看到设备没有失败地响应并且数据包清楚地到达了我运行 Wireshark 的 Linux 计算机,但是在 Windows 计算机上运行的官方程序和我自己在 Linux 计算机上运行的 Ruby 程序都没有得到响应。

我的两台电脑都有两个网络适配器,一个连接到同一个本地交换机,一个连接到另一个交换机,然后再连接到一个可以访问互联网的大型局域网。我试过在计算机之间使用不同品牌的交换机,但没有任何区别。

我在 Internet 上进行了广泛的搜索,但没有找到任何可以解决我的问题的方法。我很感激我能得到的任何帮助。

下面是用tcpdump抓到的相关数据包,第一个是我的程序发送的,第二个是设备的响应:

13:30:25.773019 IP 192.168.0.1.12345 > 225.0.0.37.12345: UDP, length 15
13:30:25.773770 IP 192.168.0.125.39129 > 225.0.0.38.12346: UDP, length 228

这是我程序中的一个(简化的)片段:

MULTICAST_SEND_ADDRESS = '225.0.0.37'
MULTICAST_SEND_PORT = 12345
MULTICAST_RESPONSE_ADDRESS = '225.0.0.38'
MULTICAST_RESPONSE_PORT = 12346
BIND_ADDRESS = '0.0.0.0'

# Transmit packet on all adapters - this part works fine
packet = [ID_STRING].pack("Z*")
addresses = Socket.ip_address_list
addresses.each do |addr|
    next unless addr.pfamily == Socket::PF_INET
    socket = UDPSocket.new
    socket.bind(addr.ip_address, MULTICAST_SEND_PORT)
    socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
    socket.send(packet, 0, MULTICAST_SEND_ADDRESS, MULTICAST_SEND_PORT)
    socket.close
end

# Receive packet - this should work, but doesn't
membership = IPAddr.new(MULTICAST_SEND_ADDRESS).hton + IPAddr.new(BIND_ADDRESS).hton
listen_socket = UDPSocket.new
listen_socket.setsockopt(Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, membership)
listen_socket.bind(BIND_ADDRESS, MULTICAST_RESPONSE_PORT)
packet, addr = listen_socket.recvfrom(1024)
# We never get to this line since there's nothing received
puts packet

最佳答案

我终于解决了这个问题。尽管我看到的所有代码示例都这么说,但您似乎无法绑定(bind)到地址“0.0.0.0”以获取多宿主计算机上的所有接口(interface)。我不知道这是否曾经有效并且已经更改或者我发现的所有示例仅在单机机器上进行了测试,但是当我将套接字绑定(bind)到正确接口(interface)的实际 ip 时它开始工作。

关于ruby - 在 Wireshark 中看到多播数据包,但用户程序未收到(Windows 和 Linux),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43322462/

相关文章:

linux - 子类型和 mDNSResponder

linux - 如何对 Mutt 进行编程以在收到新电子邮件时采取行动?

objective-c - Cocoa 中的网络多人游戏?

javascript - 下载速度下降时在 Windows 中终止进程

ruby-on-rails - 如何对嵌套资源的评论使用简单的形式?

ruby - webdriver ruby​​ 绑定(bind)中的所需功能

ruby-on-rails - rails : rescue class inheritance

ruby-on-rails - R规范 'change' : Braces or brackets?

php - 对一个命令使用不同的 PHP 版本 CLI 可执行文件

networking - OpenSSL:Wireshark 计数是 "Cipher Suites Length"还是从客户端传输到服务器的长度?