无法在 windows 10 UWP 中从 android 应用接收 UDP 广播
can't receive UDP broadcast in windows 10 UWP from android app
- 我正在使用 Xamarin.forms 和 .net Standard 2 编写 UWP 和 Android 应用程序来共享代码。
- 我正在尝试从两个应用程序发送和接收 UPD 广播,但问题是我只能从 android 应用程序按预期发送和接收,而 UWP 应用程序无法接收UDP广播包?
- 我在windows上安装了wireshark,它可以接收来自两个应用程序的所有包。
- 我为 app.uwp.exe 添加了防火墙规则(允许任何网络、任何端口、任何协议、任何 ip)我重新启动了电脑,我的 UWP 应用程序仍然无法从 android 接收应用程序。
代码:
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using System.Net.Sockets;
using System.Net;
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class ItemsPage : ContentPage
{
public async static Task<String> UDP_receive()
{
var myUDP = new UdpClient(8888);
myUDP.EnableBroadcast = true;
var myResult = await myUDP.ReceiveAsync();
myUDP.Close();
return Encoding.ASCII.GetString(myResult.Buffer) + " : " + myResult.RemoteEndPoint.Address.ToString();
}
public async static Task UDP_Send()
{
var myUDP = new UdpClient();
var RequestData = Encoding.ASCII.GetBytes(DateTime.Now.ToLongTimeString());
myUDP.EnableBroadcast = true;
await myUDP.SendAsync(RequestData, RequestData.Length, new IPEndPoint(IPAddress.Broadcast, 8888));
myUDP.Close();
}
void Button1_click(object sender, EventArgs e)
{
StartListen();
StartSending();
}
async Task StartListen()
{
Exception eXX = null;
while (eXX == null)
{
try
{
myText.Text += Environment.NewLine + await UDP_receive();
}
catch (Exception ex2)
{
eXX = ex2;
log(ex2);
}
}
}
async Task StartSending()
{
Exception eXX = null;
while (eXX == null)
{
try
{
await MyData.UDP_Send();
await Task.Delay(1000);
}
catch (Exception ex2)
{
eXX = ex2;
log(ex2);
}
}
}
}
Android 输出:
11:57:11上午:192.168.1.155
11:57:11上午:192.168.1.100
11:57:12上午:192.168.1.155
11:57:12上午:192.168.1.100
11:57:13上午:192.168.1.155
11:57:13上午:192.168.1.100
....
注意:192.168.1.100 是 Windows PC IP
UWP 输出:
11:57:11上午:192.168.1.100
11:57:12上午:192.168.1.100
11:57:13上午:192.168.1.100
11:57:14上午:192.168.1.100
11:57:15上午:192.168.1.100
....
要接收 UDP 广播,请尝试将创建与绑定分开。例如,
var myUDP = new UdpClient()
{
ExclusiveAddressUse = false,
EnableBroadcast = true
};
IPEndPoint localIPEndPoint = new IPEndPoint(myIP.BroadcastIPAddress, 8888);
myUDP.Client.Bind(localIPEndPoint);
根据我的经验,短格式构造函数(如 UdpClient(8888))似乎过早地绑定了底层套接字。这可以防止更改 EnableBroadcast 属性.
此外,从平台到平台,我发现接收广播的唯一可靠方法是使用子网的实际广播地址。捕获这些信息很容易 (?) 如下所示。
public class BroadcastAddress
{
public IPAddress IPAddress { get; set; }
public IPAddress BroadcastIPAddress { get; set; }
public NetworkInterfaceType NetworkInterfaceType { get; set; }
}
public static IEnumerable<BroadcastAddress> GetBroadcastAddresses()
{
List<BroadcastAddress> broadcastAddresses = new List<BroadcastAddress>();
NetworkInterface[] networkInterfaces = NetworkInterface.GetAllNetworkInterfaces();
foreach (NetworkInterface networkInterface in networkInterfaces)
{
if (networkInterface != null
&& (networkInterface.NetworkInterfaceType == NetworkInterfaceType.Wireless80211
|| networkInterface.NetworkInterfaceType == NetworkInterfaceType.Ethernet))
{
IPInterfaceProperties iPInterfaceProperties = networkInterface.GetIPProperties();
UnicastIPAddressInformationCollection unicastIPAddressInformationCollection = iPInterfaceProperties.UnicastAddresses;
foreach (UnicastIPAddressInformation unicastIPAddressInformation in unicastIPAddressInformationCollection)
{
if (unicastIPAddressInformation.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
{
IPAddress broadcastIPAddress =
new IPAddress(unicastIPAddressInformation.Address.Address | (UInt32.MaxValue ^ (UInt32)(unicastIPAddressInformation.IPv4Mask.Address)));
broadcastAddresses.Add(new BroadcastAddress()
{
IPAddress = unicastIPAddressInformation.Address,
BroadcastIPAddress = broadcastIPAddress,
NetworkInterfaceType = networkInterface.NetworkInterfaceType
});
}
}
}
}
return broadcastAddresses;
}
当您处理移动设备时,您只需使用 Wireless80211 广播地址。在笔记本电脑或工作站上,它可能会变得稍微复杂一些。这些设备可以有多个网络接口和每个接口上的多个子网。因此,返回列表的原因。而且,这意味着您可能需要多个 UdpClient 实例,每个子网一个。
这对 OP 来说可能为时已晚。希望这些信息可以帮助其他一些疲惫的搜索者尝试让广播正常工作(并且他们可以停止在桌子上敲打他们的额头)。
- 我正在使用 Xamarin.forms 和 .net Standard 2 编写 UWP 和 Android 应用程序来共享代码。
- 我正在尝试从两个应用程序发送和接收 UPD 广播,但问题是我只能从 android 应用程序按预期发送和接收,而 UWP 应用程序无法接收UDP广播包?
- 我在windows上安装了wireshark,它可以接收来自两个应用程序的所有包。
- 我为 app.uwp.exe 添加了防火墙规则(允许任何网络、任何端口、任何协议、任何 ip)我重新启动了电脑,我的 UWP 应用程序仍然无法从 android 接收应用程序。
代码:
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using System.Net.Sockets;
using System.Net;
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class ItemsPage : ContentPage
{
public async static Task<String> UDP_receive()
{
var myUDP = new UdpClient(8888);
myUDP.EnableBroadcast = true;
var myResult = await myUDP.ReceiveAsync();
myUDP.Close();
return Encoding.ASCII.GetString(myResult.Buffer) + " : " + myResult.RemoteEndPoint.Address.ToString();
}
public async static Task UDP_Send()
{
var myUDP = new UdpClient();
var RequestData = Encoding.ASCII.GetBytes(DateTime.Now.ToLongTimeString());
myUDP.EnableBroadcast = true;
await myUDP.SendAsync(RequestData, RequestData.Length, new IPEndPoint(IPAddress.Broadcast, 8888));
myUDP.Close();
}
void Button1_click(object sender, EventArgs e)
{
StartListen();
StartSending();
}
async Task StartListen()
{
Exception eXX = null;
while (eXX == null)
{
try
{
myText.Text += Environment.NewLine + await UDP_receive();
}
catch (Exception ex2)
{
eXX = ex2;
log(ex2);
}
}
}
async Task StartSending()
{
Exception eXX = null;
while (eXX == null)
{
try
{
await MyData.UDP_Send();
await Task.Delay(1000);
}
catch (Exception ex2)
{
eXX = ex2;
log(ex2);
}
}
}
}
Android 输出:
11:57:11上午:192.168.1.155
11:57:11上午:192.168.1.100
11:57:12上午:192.168.1.155
11:57:12上午:192.168.1.100
11:57:13上午:192.168.1.155
11:57:13上午:192.168.1.100
....
注意:192.168.1.100 是 Windows PC IP
UWP 输出:
11:57:11上午:192.168.1.100
11:57:12上午:192.168.1.100
11:57:13上午:192.168.1.100
11:57:14上午:192.168.1.100
11:57:15上午:192.168.1.100
....
要接收 UDP 广播,请尝试将创建与绑定分开。例如,
var myUDP = new UdpClient()
{
ExclusiveAddressUse = false,
EnableBroadcast = true
};
IPEndPoint localIPEndPoint = new IPEndPoint(myIP.BroadcastIPAddress, 8888);
myUDP.Client.Bind(localIPEndPoint);
根据我的经验,短格式构造函数(如 UdpClient(8888))似乎过早地绑定了底层套接字。这可以防止更改 EnableBroadcast 属性.
此外,从平台到平台,我发现接收广播的唯一可靠方法是使用子网的实际广播地址。捕获这些信息很容易 (?) 如下所示。
public class BroadcastAddress
{
public IPAddress IPAddress { get; set; }
public IPAddress BroadcastIPAddress { get; set; }
public NetworkInterfaceType NetworkInterfaceType { get; set; }
}
public static IEnumerable<BroadcastAddress> GetBroadcastAddresses()
{
List<BroadcastAddress> broadcastAddresses = new List<BroadcastAddress>();
NetworkInterface[] networkInterfaces = NetworkInterface.GetAllNetworkInterfaces();
foreach (NetworkInterface networkInterface in networkInterfaces)
{
if (networkInterface != null
&& (networkInterface.NetworkInterfaceType == NetworkInterfaceType.Wireless80211
|| networkInterface.NetworkInterfaceType == NetworkInterfaceType.Ethernet))
{
IPInterfaceProperties iPInterfaceProperties = networkInterface.GetIPProperties();
UnicastIPAddressInformationCollection unicastIPAddressInformationCollection = iPInterfaceProperties.UnicastAddresses;
foreach (UnicastIPAddressInformation unicastIPAddressInformation in unicastIPAddressInformationCollection)
{
if (unicastIPAddressInformation.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
{
IPAddress broadcastIPAddress =
new IPAddress(unicastIPAddressInformation.Address.Address | (UInt32.MaxValue ^ (UInt32)(unicastIPAddressInformation.IPv4Mask.Address)));
broadcastAddresses.Add(new BroadcastAddress()
{
IPAddress = unicastIPAddressInformation.Address,
BroadcastIPAddress = broadcastIPAddress,
NetworkInterfaceType = networkInterface.NetworkInterfaceType
});
}
}
}
}
return broadcastAddresses;
}
当您处理移动设备时,您只需使用 Wireless80211 广播地址。在笔记本电脑或工作站上,它可能会变得稍微复杂一些。这些设备可以有多个网络接口和每个接口上的多个子网。因此,返回列表的原因。而且,这意味着您可能需要多个 UdpClient 实例,每个子网一个。
这对 OP 来说可能为时已晚。希望这些信息可以帮助其他一些疲惫的搜索者尝试让广播正常工作(并且他们可以停止在桌子上敲打他们的额头)。