我在控制台应用程序中使用UDPClient
的BeginReceive
方法没有问题。但是,我无法从我的WPF应用程序运行它。我很困惑。我假设它与我从哪里调用此代码有关。我是WPF的新手。有什么我误解了UDPClient
在WPF中的绑定吗?
是否从应用程序继承可能会干扰UDPClient BeginReceive()
现在,这个代码调用堆栈从App.xaml.cs到ButtonClick()
,它创建了一个MachineItem
实例并调用StartMachine
。没有奇怪的线程或任何事情发生(除非WPF执行我在按钮点击期间不知道的事情)。再次,BeginReceive()
被称为,但如果我在Receive(IAsyncResult res)
放置一个断点,没有任何事情发生。
public partial class App : Application
{
//... all the normal stuff here
private void Button_Click(object sender, RoutedEventArgs e)
{
MachineItem currentMachine = (MachineItem)(sender as Button).DataContext;
currentMachine.StartMachine();
}
}
现在点击按钮后,会发生这种情况:
public class MachineItem : INotifyPropertyChanged
{
IPEndPoint sendersEndPoint;
UdpClient listener;
public void StartMachine()
{
listener = new UdpClient
{
ExclusiveAddressUse = false
};
listener.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
IPAddress ip = System.Net.IPAddress.Parse(this.LocalNIC_IPAddress);
int ipInt = BitConverter.ToInt32(ip.GetAddressBytes(), 0);
IPEndPoint endPoint = new IPEndPoint(ipInt, 60811); //new IPEndPoint(IPAddress.Any, listenPort); this might allow me not to know the IP of this local device!
listener.Client.Bind(endPoint);
listener.BeginReceive(new AsyncCallback(Receive), null);
Thread.Sleep(20000); // this is just for testing purposes
}
private void Receive(IAsyncResult res)
{
byte[] bytes = listener.EndReceive(res, ref sendersEndPoint);
listener.BeginReceive(new AsyncCallback(Receive), null);
Console.WriteLine("Received");
}
}
更新:我尝试将此UDP代码放在应用程序首次启动的位置,以进一步缩小问题范围。我仍然得到完全相同的行为 - 客户端能够调用BeginReceive(),但是即使UDP数据包进来也没有任何反应,换句话说,异步方法Receive()永远不会被调用...
public partial class WVGUIApp : Application
{
IPEndPoint sendersEndPoint;
UdpClient listener;
void AppStartup(object sender, StartupEventArgs args)
{
LoadMachineData();
MainWindow mainWindow = new MainWindow();
mainWindow.Show();
listener = new UdpClient
{
ExclusiveAddressUse = false
};
listener.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
IPAddress ip = System.Net.IPAddress.Parse("10.178.100.111");
int ipInt = BitConverter.ToInt32(ip.GetAddressBytes(), 0);
IPEndPoint endPoint = new IPEndPoint(ipInt, 60811); //new IPEndPoint(IPAddress.Any, listenPort); this might allow me not to know the IP of this local device!
listener.Client.Bind(endPoint);
listener.BeginReceive(new AsyncCallback(Receive), null);
//Thread.Sleep(20000);
}
private void Receive(IAsyncResult res)
{
byte[] bytes = listener.EndReceive(res, ref sendersEndPoint);
listener.BeginReceive(new AsyncCallback(Receive), null);
Console.WriteLine("Received");
}
}
经过多天的斗争,我发现了这个问题。 Windows防火墙不允许通过应用程序的调试版本。这对我来说很难诊断,因为因为允许使用UDPClient.Send(),所以不允许通过防火墙使用UDPClient.BeginReceive()。通过转到控制面板\所有控制面板项目\ Windows Defender防火墙\允许的应用程序\并单击应用程序的名称,可以在Windows 10上轻松修复此问题。允许发布版本,但调试具有与发布不同的条目。感谢MM8提供完整性检查方面的帮助。