У меня есть следующий код для чтения многоадресного сообщения, поступающего из сети, для указанного 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);
}
}
});
}
}
Я дважды вижу «Начало прослушивания правильного IP» (для моих двух IP-адресов), но по-прежнему отображаются только данные, поступающие с одной сетевой карты.
ИЗМЕНИТЬ 2
Я заметил еще кое-что странное. Если я отключу интерфейс, на котором я получаю все данные, а затем запущу программное обеспечение, я теперь буду получать данные с другого интерфейса. Если я снова активирую интерфейс и перезапущу ПО, то трафик все равно попаду на недеактивированную карту.
И я точно знаю, что у меня есть устройства, которые мне отвечают, которые подключены только к одной сети (не к обеим)
ИЗМЕНИТЬ 3
Другое дело: если я отправляю сообщение от себя (localhost) на все имеющиеся у меня сетевые карты, я вижу, что они приходят на два моих сетевых интерфейса. НО, если я запущу свою программу дважды, только первая программа получит сообщения, а не вторая.
Изменить 4
Дополнительная информация после первого комментария: у меня две сетевые карты, одна с 10.10.24.78
ip, другая с 10.9.10.234
ip. Это не я отправляю данные, а сетевые части (порт 5353
с этим ip-адресом является известным многоадресным адресом, используемым для mDNS, поэтому я должен получать трафик от таких вещей, как принтер, itunes, macs и некоторые другие части программного обеспечения, которое мы создали). Данные передаются многоадресно на 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);
}
}
}
EDIT 5 Вот результат моей route print
(не знал этой команды), и на двух моих IP-адресах я всегда получаю данные на 10.9.10.234
Изменить 6
Я пробовал несколько других вещей:
- Используйте сокет для получения вместо UdpClient --> Не работает
- Установите дополнительную опцию socketOption для считывателя (DontRoute = 1, Broadcast = 1) --> Не работает
- Укажите MulticastInterface, который должен использовать читатель Socket (используя socketOption MulticastInterface) --> Не работает
route print
? - person PCoder   schedule 07.03.2013SocketOptionName.MulticastInterface
, но это ничего не изменило - person J4N   schedule 07.03.2013