如何选择通过其发送UDP广播数据包的网络接口

时间:2012-02-03 10:42:46

标签: ruby sockets networking udp

如果我发送包含'foo'的UDP数据包,请执行以下操作:

socket = UDPSocket.new
socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
socket.send('foo', 0, '<broadcast>', 40001)

然后wireshark告诉我数据包被正确发送,但不幸的是它的源地址是192.168.0.3。由于我的服务器正在侦听localhost:40001,这意味着它没有收到数据包。我不想让服务器监听0.0.0.0,因为它不应该接收在另一个网络中发送的类似UDP请求。我可以让服务器在192.168.0.0/24网络内监听,但稍后它将从另一个网络监听,既不是localhost也不是192.168.0.0/24,因此无法解决问题。

有没有办法选择客户端套接字发送其数据包的源地址(以及通过它的接口)?

3 个答案:

答案 0 :(得分:2)

我猜你是想把它发送到环回设备,所以它应该是这样的(从来没有用ruby试过这个):

dev="lo"
socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_BINDTODEVICE, dev+'\0'))

您可能还必须启用多播循环:

socket.setsockopt(Socket::SOL_SOCKET, Socket::IP_MULTICAST_LOOP, [1].pack('i'))

答案 1 :(得分:1)

你有没有试过bind()?一般来说,如果您socket.bind()到某个地址(例如127.0.0.1),那么您的数据包应该来自该地址。可能会特别对待环回和广播,但bind()将是我尝试的首选。

答案 2 :(得分:0)

答案出现两年太晚,但这可能有助于未来的StackOverflow用户。看起来您需要使用套接字选项IP_MULTICAST_IF,它接受​​您的接口地址的网络订购DWORD版本。幸运的是,ipaddr库有一个用于转换人类可读地址的实用方法:

address = '127.0.0.1'
hton = IPAddr.new(address).hton
socket.setsockopt(Socket::IPPROTO_IP, Socket::IP_MULTICAST_IF, hton)