为什么我的 UDP 多播无法到达网络上的计算机?
我正在尝试使用 UDP 多播设置自动发现,并使用来自互联网的一些示例代码。当我在同一台机器上运行客户端和服务器时,这似乎工作正常,但是当我在不同的机器上运行它们时,无论是在我的机器(virtualBox)上的虚拟机中运行的机器还是在其他“真实”机器上运行的机器网络,那么其他机器似乎永远不会收到正在广播的消息。
经过一番谷歌搜索后,似乎罪魁祸首可能是路由器(SpeedTouch 780),它可能会丢弃数据包。我如何检查是否属于这种情况?我可以检查他们的其他内容来尝试找出问题吗?可能完全是别的东西吗?
teh codez:
服务器代码
using System;
using System.Net.Sockets;
using System.Text;
internal class StockPriceMulticaster
{
private static string[] symbols = {"ABCD", "EFGH", "IJKL", "MNOP"};
public static void Main ()
{
using (UdpClient publisher = new UdpClient ("230.0.0.1", 8899))
{
Console.WriteLine ("Publishing stock prices to 230.0.0.1:8899");
Random gen = new Random ();
while (true)
{
int i = gen.Next (0, symbols.Length);
double price = 400*gen.NextDouble () + 100;
string msg = String.Format ("{0} {1:#.00}", symbols, price);
byte[] sdata = Encoding.ASCII.GetBytes (msg);
publisher.Send (sdata, sdata.Length);
System.Threading.Thread.Sleep (5000);
}
}
}
}
和客户端:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
class StockPriceReceiver{
public static void Main(){
UdpClient subscriber = new UdpClient(8899);
IPAddress addr = IPAddress.Parse("230.0.0.1");
subscriber.JoinMulticastGroup(addr);
IPEndPoint ep = null;
for(int i=0; i<10;i++){
byte[] pdata = subscriber.Receive(ref ep);
string price = Encoding.ASCII.GetString(pdata);
Console.WriteLine(price);
}
subscriber.DropMulticastGroup(addr);
}
}
编辑
因此,由于某种原因,它似乎仅在 VirtualBox 主机网络接口上发布 UDP 数据包,而不是在所有计算机都连接到的无线网络上发布。只需要弄清楚如何让它不这样做...... 所以在答案中添加了解决方案......
I am trying to set up auto discovery using UDP multicasting, and am using some sample code from the internet. this seems to work ok when I run the client and the server on the same machine, but when I run them on different machines, either with a machine running in a VM on my machine (virtualBox) or on other 'real' machines on the network then the other machines never seem to receive the messages being broadcast.
After some googling it seems the likely culprit would be the router (SpeedTouch 780) which might be dropping the packets. How can I check if this is the case? Are their other things which I can check to try and track down the problem? Might it be something else entirely?
teh codez:
server code
using System;
using System.Net.Sockets;
using System.Text;
internal class StockPriceMulticaster
{
private static string[] symbols = {"ABCD", "EFGH", "IJKL", "MNOP"};
public static void Main ()
{
using (UdpClient publisher = new UdpClient ("230.0.0.1", 8899))
{
Console.WriteLine ("Publishing stock prices to 230.0.0.1:8899");
Random gen = new Random ();
while (true)
{
int i = gen.Next (0, symbols.Length);
double price = 400*gen.NextDouble () + 100;
string msg = String.Format ("{0} {1:#.00}", symbols, price);
byte[] sdata = Encoding.ASCII.GetBytes (msg);
publisher.Send (sdata, sdata.Length);
System.Threading.Thread.Sleep (5000);
}
}
}
}
and the client:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
class StockPriceReceiver{
public static void Main(){
UdpClient subscriber = new UdpClient(8899);
IPAddress addr = IPAddress.Parse("230.0.0.1");
subscriber.JoinMulticastGroup(addr);
IPEndPoint ep = null;
for(int i=0; i<10;i++){
byte[] pdata = subscriber.Receive(ref ep);
string price = Encoding.ASCII.GetString(pdata);
Console.WriteLine(price);
}
subscriber.DropMulticastGroup(addr);
}
}
EDIT
So it seems that it is publishing the UDP packets on the VirtualBox host only network interface for some reason rather than the wireless network that all the machines are connected to. Just need to figure out how to make it not do that...
So added the resolution in an answer instead...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我会尝试 Wireshark。
I'd try Wireshark.
这里有几个问题需要研究。
第一个是:您确定多播是执行此操作的最佳方法吗?我认为广播会更好地为您服务。
另一个是:路由器一般不转发多播或广播,而交换机和集线器则转发。
看看下面两个问题:
为什么没有收到(UDP 多播)数据包? 和通过互联网进行 UDP 多播?
编辑:
当您创建 UdpClient 时,您可以指定哪个本地您将从中发送的端点。 http://msdn.microsoft.com/en-us/library/k227d11f。 ASPX
There are a few issues to look into here.
The first is: are you sure multicast is the best way of doing this? I think broadcast would serve you better.
The other is: routers generally don't forward multicast or broadcast, switches and hubs do.
Take a look at the following two questions:
Why are (UDP multicast) packets not being received? and UDP Multicast over the internet?
EDIT:
When you create your UdpClient you can specify which local endpoint you will be sending from. http://msdn.microsoft.com/en-us/library/k227d11f.aspx
在您的代码中,您没有为对 UdpClient 的调用设置 TTL。因此,如果默认 TTL 为 1,那么您的数据包将不会通过第一个路由器。
In your code, you do not setup the TTL for your call to UdpClient. So if the default TTL is 1, then your packets won't get past the first router.
所以问题是,由于我有超过 1 个活动网络连接,因此它选择一个并使用它,这导致 UDP 数据包在客户端正在侦听的不同网络连接上发送。由于我安装了 Virtual Box,因此它已安装并激活 VirtualBox 仅主机网络适配器,因此可以支持仅主机网络连接。当我将 VirtualBox 切换到仅主机模式时,开始接收数据包。禁用 VirtualBox 适配器并切换回桥接连接也有效。
So the issue turned out to be that as I had more than 1 active network connection it was choosing one and using that and that was causing the UDP packets to be sent out on a different network connection that the client was listening on. As i had installed Virtual box it had installed and activated the VirtualBox Host-only network adapter, so that host only network connections could be supported. When I switched VirtualBox over to host only mode the packets started to be received. Disabling the VirtualBox adapter and switching back to a bridged connection also worked.
如果您有多个界面,那么正确的答案是听取所有界面的意见,如果您没有正确的定义,则不要尝试选择一个。
以下是我实现 UDP 发现服务的方法。它最初崩溃是因为我的 Virtual Box 接口妨碍并吞没了随机 IP 子网 (192.168.56.x) 上的 UDP 广播,而不是我实际的以太网连接 (192.168.0.x)。所以我根据古格的回答改进了它。它有点冗长,我可能没有以最简洁的方式编写它,但它现在可以工作了。我在所有接口上广播,然后
在所有接口上接收数据(循环),直到超时或单个响应(如果
justFindOne = true
)。由于某种原因,IPv6 接口使 UDP 部分崩溃,所以我只过滤掉 IPv4 地址。如果有办法让这对两者都起作用,请纠正我。
If you have multiple interfaces, the right answer is to listen to all of them, and not try to pick one if you do not have a definition of what is right.
Here's how I implemented a UDP discovery service. It broke, originally, because my Virtual Box interfaces got in the way and swallowed up the UDP broadcasts on a random IP subnet (192.168.56.x) instead of my actual ethernet connection (192.168.0.x). So I improved it, based on the answer from Guge. It's a little verbose and I probably didn't code it in the most neat way, but it works now. I broadcast on all interfaces, then
receive the data (round-robin) on all interfaces until the timeout, or single response (if
justFindOne = true
).For some reason, IPv6 interfaces crash the UDP part, so I just filter out IPv4 addresses. Please correct me if there is a way for this to work on both.