我正在调试一个奇怪的问题,发生在实时环境中的一台机器上 .
我的应用程序(从属)应该在任何时候从LAN中的另一台主机(主机)接收UDP多播消息,但显然它只在从机先前已发送消息时才这样做 .
我的期望是:
-
Slave要求提供数据
-
Master发送数据
-
奴隶接收和消费
-
师父等2-3分钟
-
Master发送新数据
-
Slave接收并使用新数据
-
重复步骤4到6
我看到的是:
- 奴隶没有收到任何东西
但是,如果我让奴隶连续要求新数据(轮询,即重复步骤1),我终于得到了消息 .
我在Wireshark中看到来自主服务器的消息确实是由从属主机接收的 . 只是我的应用程序没有收到它 . 更令人惊讶的是,在相同网络上运行的另一个主从对,使用相同的应用程序,工作正常,以及我在测试环境中的配对 .
slave应用程序在异步模式下使用 UdpClient
. 以下是监听器的初始化方式:
private void ListenMain()
{
try
{
UdpClient udpClient = new UdpClient();
udpClient.Client.ExclusiveAddressUse = false;
udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 1000);
IPv4InterfaceProperties p = adapter.GetIPProperties().GetIPv4Properties();
udpClient.Client.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastInterface, (int)IPAddress.HostToNetworkOrder(p.Index));
udpClient.Client.Bind(endPoint);
udpClient.JoinMulticastGroup(12345);
ListenState listenState = new ListenState();
listenState.udpClient = udpClient;
listenStates.Add(listenState);
logger.Debug("Waiting for messages");
udpClient.BeginReceive(new AsyncCallback(OnPacketReceived), listenState);
}
catch (Exception e)
{
logger.Error(e, "ListenMain() encountered an error");
}
}
这是收到的数据包的处理程序:
private void OnPacketReceived(IAsyncResult result)
{
logger.Trace("OnPacketReceived");
IPEndPoint recvAddress = new IPEndPoint(IPAddress.Any, MULTICAST_PORT);
ListenState state = result.AsyncState as ListenState;
byte[] receive_byte_array;
try
{
logger.Trace("before EndReceive");
receive_byte_array = state.udpClient.EndReceive(result, ref recvAddress);
logger.Trace("after EndReceive, got {0} bytes", receive_byte_array.Length);
// packet handling goes here...
// do the loop
logger.Trace("waiting for another packet");
state.udpClient.BeginReceive(new AsyncCallback(OnPacketReceived), state);
}
catch (ObjectDisposedException)
{
logger.Info("Socket is now closed");
return;
}
catch (Exception e)
{
logger.Warn(e, "exception in handling incoming message");
}
}
当然,轮询新数据不是最佳解决方案,并且会引入不必要的延迟 . 我想知道哪个现象会导致UdpClient丢失传入的数据包,除非之前有相同的UdpClient发送了一些内容 .