为什么我收不到发送到我自己 IP 的 UDP 数据包?
我编写了这个 ruby 程序来将 UDP 数据包发送到端口 16800:
require 'socket'
sock = UDPSocket.new
sock.bind("", 47123)
sock.send("Hello!", 0, "192.168.0.100", 16800)
sock.close
其中 192.168.0.100 是我自己的 IP 地址。但是,该数据包不会在 Wireshark 中显示,并且我在同一台 PC(运行 Linux)上侦听端口 16800 的 UDP 服务器没有收到任何内容。
当我稍微重写程序到
require 'socket'
sock = UDPSocket.new
sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
sock.bind("", 47123)
sock.send("Hello!", 0, "<broadcast>", 16800)
sock.close
数据包时,数据包确实出现在 Wireshark 中,但我的服务器仍然没有收到任何内容。
我错过了一些明显的东西吗?
编辑: 服务器代码,为了完整性
require 'socket'
sock = UDPSocket.new
sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
sock.bind(nil, 16800)
while true
packet = sock.recvfrom(1024)
puts packet
end
但是,这是从互联网上的某个地方复制的,在为 stackoverflow 编辑它时,我发现服务器总是接收发送到 127.0.0.1 的数据包,但是当我将 nil 更改为“”时,服务器突然也接收上面发送的数据包。这是 ruby 套接字实现中的错误吗?
I've written this ruby program to send a UDP Packet to port 16800:
require 'socket'
sock = UDPSocket.new
sock.bind("", 47123)
sock.send("Hello!", 0, "192.168.0.100", 16800)
sock.close
where 192.168.0.100 is my own ip address. However, the packet doesn't show in Wireshark and my UDP server listening on port 16800 on the same PC (running Linux) isn't receiving anything.
When I slightly rewrite the program to
require 'socket'
sock = UDPSocket.new
sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
sock.bind("", 47123)
sock.send("Hello!", 0, "<broadcast>", 16800)
sock.close
the packet does show up in Wireshark, but my server still isn't receiving anything.
Am I missing something obvious?
EDIT:
The server code, for completeness
require 'socket'
sock = UDPSocket.new
sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
sock.bind(nil, 16800)
while true
packet = sock.recvfrom(1024)
puts packet
end
However, this was copied somewhere from the internet, and while editing it for stackoverflow, i found out that the server always receives packets sent to 127.0.0.1 but when I change nil to "", the server suddenly also receives the packets sent above. Is this a bug in the ruby socket implementation?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我刚刚使用了您的代码,问题是您没有绑定到特定的 IP 地址。我不了解 Linux,但在 OS X 上存在一个问题,有时默认值会连接到未使用的 IP6 地址,而不是您期望的接口。
在服务器上将“”更改为192.168.1.255,并在客户端的绑定上包含“192.168.1.255”,这一切对我来说都有效:)
I just used your very code and the problem is you're not binding to a specific IP address. I don't know about Linux but on OS X there's an issue where sometimes the default will attach to an unused IP6 address rather than the interface you were expecting.
Changing "" to 192.168.1.255 on the server, and including "192.168.1.255" on the bind in the client made all this work for me :)
UDPSocket.BIND 需要一个主机和一个端口。尝试将 nil 更改为您的 IP 地址。来自 http://coderrr.wordpress.com/ 2008/05/28/获取您的本地 IP 地址/;用于
获取您的IP
UDPSocket.BIND takes a host and a port. Try changing the nil to your IP address. From http://coderrr.wordpress.com/2008/05/28/get-your-local-ip-address/; use
to get your IP
您是否尝试过发送到“localhost”或“127.0.0.1”?这将直接发送到本地计算机,并有助于进一步诊断问题。
Have you tried sending to "localhost" or "127.0.0.1"? This will send directly to the local computer and will help diagnose the problem further.
这里有点推测,但你可能想考虑这样的事情 - 当你使用计算机自己的 IP 时,数据包在物理链路上不可见,因为 tcp/ip 堆栈不必将它们推那么远为了让它们到达目的地,它可以在内部将它们转向七层堆栈模型中较高层之一的计算机(也许是“传输”层?)
Kind of speculating here, but you might want to consider something like this - when you use the computer's own IP, the packets aren't visible on the physical link b/c the tcp/ip stack doesn't have to push them that far to get them where they are going, it can turn them around internally to the computer at one of the higher layers in that seven-layer stack model (the 'transport' layer, perhaps?)
如果这样的连接应该可以工作,并且您看到使用 Wireshark 的软件包,那么您还应该检查计算机上的软件防火墙。如果它阻止了您想要使用的 UDP 端口的流量,您仍然可以使用 Wireshark 查看该包!
If such a connection is supposed to work, and you see the packages using Wireshark, then you should also check the software firewall on your machine. If it blocks traffic to the UDP port you want to use you can still see the package using Wireshark!