无法使 UDP.BeginReceive 在 WPF 中工作

Unable to get UDP.BeginReceive to work in WPF

我可以在控制台应用程序中使用 UDPClientBeginReceive 方法。但是,我无法从我的 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() 通过防火墙。通过转到控制 Panel\All 控制面板 Items\Windows Defender Firewall\Allowed 应用程序\ 并单击应用程序的名称,可以很容易地在 windows 10 上修复此问题。允许发布版本通过,但调试具有与发布不同的条目。感谢 MM8 帮助进行完整性检查。