【发布时间】:2013-02-22 07:44:30
【问题描述】:
我有以下代码来读取来自网络的多播消息,用于指定的 IP+端口
private static void ReceiveMessages(int port, string ip, CancellationToken token)
{
Task.Factory.StartNew(() =>
{
using (var mUdpClientReceiver = new UdpClient())
{
var mReceivingEndPoint = new IPEndPoint(IPAddress.Any, port);
mUdpClientReceiver.ExclusiveAddressUse = false;
mUdpClientReceiver.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
mUdpClientReceiver.ExclusiveAddressUse = false;
mUdpClientReceiver.Client.Bind(mReceivingEndPoint);
mUdpClientReceiver.JoinMulticastGroup(IPAddress.Parse(ip), 255);
while (!token.IsCancellationRequested)
{
byte[] receive = mUdpClientReceiver.Receive(ref mReceivingEndPoint);
Console.WriteLine("Message received from {0} ",mReceivingEndPoint);
}
}
});
}
我有两个网络适配器,我有来自这个多播 ip+端口的数据(由两个监控每个网络适配器的wireshark 实例确认)。我在wireshark上看到两个网卡的这些端口+Ip)上都有很多流量。
问题是在我的控制台上,我只能看到来自一张网卡的消息。
我仔细检查了 netstat,我的端口上没有任何其他软件正在监听:
那么为什么我只能从我的两张网卡中的一张获得流量?
编辑:
我什至尝试了以下方法:
private static void ReceiveMessages(int port, string ip, CancellationToken token, IEnumerable<IPAddress> ipAddresses)
{
foreach (IPAddress ipAddress in ipAddresses)
{
IPAddress ipToUse = ipAddress;
Task.Factory.StartNew(() =>
{
using (var mUdpClientReceiver = new UdpClient())
{
var mReceivingEndPoint = new IPEndPoint(ipToUse, port);
mUdpClientReceiver.ExclusiveAddressUse = false;
mUdpClientReceiver.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
mUdpClientReceiver.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
mUdpClientReceiver.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontRoute, 1);
mUdpClientReceiver.ExclusiveAddressUse = false;
mUdpClientReceiver.Client.Bind(mReceivingEndPoint);
mUdpClientReceiver.JoinMulticastGroup(IPAddress.Parse(ip), 255);
Console.WriteLine("Starting to listen on "+ipToUse);
while (!token.IsCancellationRequested)
{
byte[] receive = mUdpClientReceiver.Receive(ref mReceivingEndPoint);
Console.WriteLine("Message received from {0} on {1}", mReceivingEndPoint,ipToUse);
}
}
});
}
}
我看到两次“开始监听 theCorrectIP”(对于我的两个 IP),但它仍然只显示来自一张网卡的数据。
编辑 2
我确实也注意到了一些奇怪的东西。如果我禁用接收所有数据的接口,然后启动软件,我现在从另一个接口获取数据。如果我再次激活接口并重新启动软件,我仍然会在未激活的卡上获得流量。
而且我确定我有响应我的设备,这些设备只连接到一个网络(不是两个)
编辑 3
另一件事:如果我从我(本地主机)发送一条消息,在我拥有的所有网卡上,我会看到它们出现在我的两个网络接口上。但是,如果我启动我的程序两次,只有第一个程序会收到消息,而不是第二个。
编辑 4
附加信息,在第一条评论之后:
我有两张以太网卡,一张带有10.10.24.78 ip,另一张带有10.9.10.234 ip。
发送数据的不是我,而是网络片段(带有此 ip 的端口5353 是用于 mDNS 的已知多播地址,所以我应该接收来自打印机、iTunes、Mac 和我们创建的其他一些软件的流量)。数据在ip上多播
224.0.0.251 和端口5353。
这是一个代码,您可以使用它在多个 IP 上发送数据,但就像我描述的那样,如果您在本地启动它几乎可以工作(除了只有一个本地客户端接收消息)。
private static void SendManuallyOnAllCards(int port, string multicastAddress, IEnumerable<IPAddress> ipAddresses)
{
foreach (IPAddress remoteAddress in ipAddresses)
{
IPAddress ipToUse = remoteAddress;
using (var mSendSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
{
mSendSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership,
new MulticastOption(IPAddress.Parse(multicastAddress)));
mSendSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 255);
mSendSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
var ipep = new IPEndPoint(ipToUse, port);
//IPEndPoint ipep = new IPEndPoint(IPAddress.Parse(multicastAddress), port);
mSendSocket.Bind(ipep);
mSendSocket.Connect(ipep);
byte[] bytes = Encoding.ASCII.GetBytes("This is my welcome message");
mSendSocket.Send(bytes, bytes.Length, SocketFlags.None);
}
}
}
编辑 5
这是我的route print(不知道那个命令)的结果,在我的两个IP上,我总是在10.9.10.234上接收数据
编辑 6
我尝试了其他几件事:
- 使用套接字而不是 UdpClient 接收 --> 无效
- 在阅读器上设置一些额外的socketOption(DontRoute =1,Broadcast=1)-->没用
- 指定读卡器Socket必须使用的MulticastInterface(使用socketOption MulticastInterface)-->没用
【问题讨论】:
-
您的接口是什么(以太网、eth/wlan)?您在这些接口上有哪些 IP?如果您能分析一下您是如何发送多播消息的,那将会更有帮助。
-
@PCoder :感谢您的评论,我在最初的问题上添加了一些细节(编辑 4)
-
你能告诉我们你的
route print命令的输出吗? -
@PCoder: 有什么可以帮助的,我真的很绝望(而且我不是网络专家:()。我用结果编辑了问题
-
我同意你的问题确实很棘手,我也没有解决方案:(。我发现了一个与你的问题非常相似的问题,也许这会有所帮助。http://linux.derkeiler.com/Newsgroups/comp.os.linux.networking/2009-09/msg00223.html
标签: c# sockets network-programming udp udpclient