C# Windows Phone 8.1没有';不发送UDP广播

C# Windows Phone 8.1没有';不发送UDP广播,c#,.net,sockets,windows-phone-8.1,C#,.net,Sockets,Windows Phone 8.1,我正在尝试使用Windows Phone 8.1发送UDP广播。因此,我创建了一个UDP服务器(一个控制台应用程序),它在我的笔记本电脑上与我的WP8.1运行在同一个Wifi网络中 这是测试服务器: static void Main(string[] args) { var client = new UdpClient(12345); client.MulticastLoopback = false; var isRunning = true; var thr

我正在尝试使用Windows Phone 8.1发送UDP广播。因此,我创建了一个UDP服务器(一个控制台应用程序),它在我的笔记本电脑上与我的WP8.1运行在同一个Wifi网络中

这是测试服务器:

static void Main(string[] args)
{
    var client = new UdpClient(12345);
    client.MulticastLoopback = false;

    var isRunning = true;

    var thread = new Thread(() =>
    {
        while (isRunning)
        {
            var endpoint = new IPEndPoint(IPAddress.Any, 0);
            var data = client.Receive(ref endpoint);

            Console.WriteLine("Received message from {0}:{1} with length={2}", endpoint.Address, endpoint.Port, data.Length);
            client.Send(data, data.Length, endpoint);
        }
    });

    thread.Start();

    Console.ReadLine();
    isRunning = false;
}
当我创建另一个控制台应用程序以UDP广播的形式发送一些数据时,我将从服务器获得与响应相同的数据。所以服务器工作正常。对于Windows Phone 8.1,我必须使用DatagramSocket。这是我的代码:

var socket = new DatagramSocket();
socket.MessageReceived += HandleIncomingMessages;
using (var stream = await socket.GetOutputStreamAsync(new HostName("255.255.255.255"), "12345"))
{
    await stream.WriteAsync(data.AsBuffer());
    await stream.FlushAsync();
}
我还使用了一个附加的
await_socket.ConnectAsync(新主机名(“255.255.255.255”),“12345”)socket
对象后的code>


不幸的是,我永远也得不到答案。

这是我对支持广播的UdpClient的实现

public class UdpClient : IDisposable
{
    private readonly DatagramSocket _socket;
    private readonly BlockingCollection<Tuple<IpAddress, byte[]>> _incomingMessages;
    private readonly IpAddress _ipAddress;
    private readonly object _lock = new object();
    private bool _isBound;
    private bool _isBinding;

    public UdpClient(IpAddress ipAddress)
    {
        _ipAddress = ipAddress;
        _socket = new DatagramSocket();
        _socket.Control.DontFragment = true;
        _incomingMessages = new BlockingCollection<Tuple<IpAddress, byte[]>>();
        _socket.MessageReceived += HandleIncomingMessages;
    }

    public async Task SendAsync(byte[] data)
    {
        try
        {
            await Connect();

            using (var stream = await _socket.GetOutputStreamAsync(_ipAddress.Host, _ipAddress.ServiceName))
            {
                await stream.WriteAsync(data.AsBuffer(0, data.Length));
            }
        }
        catch (Exception e)
        {
            Debug.WriteLine(e);
        }
    }

    public bool TryGetIncomingMessage(out Tuple<IpAddress, byte[]> message)
    {
        return _incomingMessages.TryTake(out message, TimeSpan.FromMilliseconds(20));
    }

    public void Dispose()
    {
        _socket.Dispose();
    }

    private async Task Connect()
    {
        if (_isBound || _isBinding)
        {
            return;
        }

        lock (_lock)
        {
            if (_isBound || _isBinding)
            {
                return;
            }

            _isBinding = true;
        }

        var possibleConnectionProfiles = NetworkInformation.GetConnectionProfiles()
            .Where(p => p.IsWlanConnectionProfile && p.GetNetworkConnectivityLevel() != NetworkConnectivityLevel.None)
            .ToList();

        var connectionProfile = possibleConnectionProfiles.FirstOrDefault();

        if (connectionProfile != null)
        {
            await _socket.BindServiceNameAsync(_ipAddress.ServiceName, connectionProfile.NetworkAdapter);
        }

        _isBound = true;
        _isBinding = false;
    }

    private void HandleIncomingMessages(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs e)
    {
        var address = e.RemoteAddress.ToString();
        var port = int.Parse(e.RemotePort);

        using (var reader = e.GetDataReader())
        {
            var data = reader.DetachBuffer().ToArray();
            _incomingMessages.Add(Tuple.Create(new IpAddress(address, port), data));
        }
    }
}

public struct IpAddress
{
    public static readonly IpAddress Broadcast = new IpAddress("255.255.255.255");

    public readonly string Address;
    public readonly int Port;
    public readonly HostName Host;
    public readonly string ServiceName;

    public IpAddress(string address, int port)
    {
        Address = address;
        Port = port;
        Host = new HostName(address);
        ServiceName = port.ToString(CultureInfo.InvariantCulture);
    }

    public override string ToString()
    {
        return string.Format(CultureInfo.InvariantCulture, "{0}:{1}", Address, Port);
    }

    public bool Equals(IpAddress other)
    {
        return string.Equals(Address, other.Address) && Port == other.Port;
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj))
            return false;
        return obj is IpAddress && Equals((IpAddress)obj);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            return ((Address != null ? Address.GetHashCode() : 0) * 397) ^ Port;
        }
    }
}
公共类UdpClient:IDisposable
{
专用只读DatagramSocket _套接字;
私人只读阻止收集信息;
专用只读IP地址\u IP地址;
私有只读对象_lock=新对象();
私人住宅区;
私人文件具有约束力;
公共UdpClient(IpAddress IpAddress)
{
_IP地址=IP地址;
_套接字=新的DatagramSocket();
_socket.Control.DontFragment=true;
_incomingMessages=新建BlockingCollection();
_socket.MessageReceived+=HandleIncomingMessages;
}
公共异步任务SendAsync(字节[]数据)
{
尝试
{
等待连接();
使用(var stream=await _socket.GetOutputStreamAsync(_ipAddress.Host,_ipAddress.ServiceName))
{
wait stream.WriteAsync(data.AsBuffer(0,data.Length));
}
}
捕获(例外e)
{
Debug.WriteLine(e);
}
}
public bool TryGettingComingMessage(输出元组消息)
{
返回_incomingMessages.TryTake(out message,TimeSpan.frommissions(20));
}
公共空间处置()
{
_socket.Dispose();
}
专用异步任务连接()
{
如果(|isBinding | | isBinding)
{
返回;
}
锁
{
如果(|isBinding | | isBinding)
{
返回;
}
_isBinding=true;
}
var possibleConnectionProfiles=NetworkInformation.GetConnectionProfiles()
.Where(p=>p.IsWlanConnectionProfile&&p.getNetworkConnectionTylevel()!=networkConnectionTylevel.None)
.ToList();
var connectionProfile=possibleConnectionProfiles.FirstOrDefault();
if(connectionProfile!=null)
{
wait _socket.BindServiceNameAsync(_ipAddress.ServiceName,connectionProfile.NetworkAdapter);
}
_isBound=true;
_isBinding=false;
}
私有void HandleIncomingMessages(DatagramSocket发送方、DatagramSocketMessageReceivedEventArgs e)
{
var address=e.RemoteAddress.ToString();
var port=int.Parse(例如,RemotePort);
使用(var reader=e.GetDataReader())
{
var data=reader.DetachBuffer().ToArray();
_incomingMessages.Add(Tuple.Create(新IpAddress(地址、端口)、数据));
}
}
}
公共结构IP地址
{
公共静态只读IP地址广播=新IP地址(“255.255.255.255”);
公共只读字符串地址;
公共只读int端口;
公共只读主机名主机;
公共只读字符串ServiceName;
公共IP地址(字符串地址,int端口)
{
地址=地址;
端口=端口;
主机=新主机名(地址);
ServiceName=port.ToString(CultureInfo.InvariantCulture);
}
公共重写字符串ToString()
{
返回string.Format(CultureInfo.InvariantCulture,“{0}:{1}”,地址,端口);
}
公共布尔等于(IP地址其他)
{
返回字符串.Equals(Address,other.Address)&&Port==other.Port;
}
公共覆盖布尔等于(对象对象对象)
{
if(ReferenceEquals(null,obj))
返回false;
返回obj为IpAddress&&Equals((IpAddress)obj);
}
公共覆盖int GetHashCode()
{
未经检查
{
返回((Address!=null?Address.GetHashCode():0)*397)^端口;
}
}
}
我曾读到,向255.255.255.255广播消息不是一个好习惯。而是应该发送到本地广播地址,如(即192.168.1.255

为此,我编写了以下IpAddressProvider:

public static class IpProvider
{
    private static readonly Lazy<string> _localAddress;
    private static readonly Lazy<string> _broadcastAddress;

    static IpProvider()
    {
        _localAddress = new Lazy<string>(GetLocalAddress);
        _broadcastAddress = new Lazy<string>(GetBroadcastAddress);
    }

    public static string LocalAddress { get { return _localAddress.Value; } }

    public static string BroadcastAddress { get { return _broadcastAddress.Value; } }

    private static string GetLocalAddress()
    {
        var hostnames = NetworkInformation.GetHostNames();
        foreach (var hn in hostnames)
        {
            //IanaInterfaceType == 71 => Wifi
            //IanaInterfaceType == 6 => Ethernet (Emulator)
            if (hn.IPInformation != null &&
                (hn.IPInformation.NetworkAdapter.IanaInterfaceType == 71
                 || hn.IPInformation.NetworkAdapter.IanaInterfaceType == 6))
            {
                return hn.DisplayName;
            }
        }

        return IpAddress.Broadcast.Address;
    }

    private static string GetBroadcastAddress()
    {
        var parts = _localAddress.Value.Split(new[] { '.' }).Take(3);
        return string.Join(".", parts) + ".255";
    }
}
公共静态类IpProvider
{
私有静态只读懒本地地址;
私有静态只读惰性广播地址;
静态IpProvider()
{
_localAddress=new Lazy(GetLocalAddress);
_broadcastAddress=new Lazy(GetBroadcastAddress);
}
公共静态字符串LocalAddress{get{return\u LocalAddress.Value;}}
公共静态字符串BroadcastAddress{get{return\u BroadcastAddress.Value;}}
私有静态字符串GetLocalAddress()
{
var hostnames=NetworkInformation.GetHostNames();
foreach(主机名中的变量hn)
{
//IanaInterfaceType==71=>Wifi
//IanaInterfaceType==6=>Ethernet(仿真器)
如果(hn.IPInformation!=null&&
(hn.ipinfo.NetworkAdapter.IanaInterfaceType==71
||hn.ipinfo.NetworkAdapter.IanaInterfaceType==6))
{
返回hn.DisplayName;
}
}
返回IpAddress.Broadcast.Address;
}
私有静态字符串GetBroadcastAddress()
{
var parts=_localAddress.Value.Split(new[]{.'.}).Take(3);
返回字符串.Join(“.”,parts)+.255”;
}
}
现在我用它们一起发送广播信息:

var gatewayAddress = new IpAddress(IpProvider.BroadcastAddress);
var udpClient = new UdpClient(gatewayAddress);
await udpClient.SendAsync(data);

Tuple<IpAddress, byte[]> message;
while (udpClient.TryGetIncomingMessage(out message))
{
    if (message.Item1.Address == IpProvider.LocalAddress)
    {
        continue;
    }

    HandleIncomingPacket(message);
}
var gatewayAddress=新的IpAddress(IpProvider.BroadcastAddress);
var udpClient=新的udpClient(网关地址);
等待udpClient.SendAsync(数据);
元组信息;
wh