如何使用UDP广播进行网络发现

NTK*_*K88 25 c# udp

我想在C#中使用UDP Broadcast进行网络发现.我不知道该怎么做.你能告诉我怎么做的建议吗?

我想做这个教程.

ruf*_*nov 34

在C#中做同样的事情非常简单

服务器:

var Server = new UdpClient(8888);
var ResponseData = Encoding.ASCII.GetBytes("SomeResponseData");

while (true)
{
    var ClientEp = new IPEndPoint(IPAddress.Any, 0);
    var ClientRequestData = Server.Receive(ref ClientEp);
    var ClientRequest = Encoding.ASCII.GetString(ClientRequestData);

    Console.WriteLine("Recived {0} from {1}, sending response", ClientRequest, ClientEp.Address.ToString());
    Server.Send(ResponseData, ResponseData.Length, ClientEp);
}
Run Code Online (Sandbox Code Playgroud)

客户:

var Client = new UdpClient();
var RequestData = Encoding.ASCII.GetBytes("SomeRequestData");
var ServerEp = new IPEndPoint(IPAddress.Any, 0);

Client.EnableBroadcast = true;
Client.Send(RequestData, RequestData.Length, new IPEndPoint(IPAddress.Broadcast, 8888));

var ServerResponseData = Client.Receive(ref ServerEp);
var ServerResponse = Encoding.ASCII.GetString(ServerResponseData);
Console.WriteLine("Recived {0} from {1}", ServerResponse, ServerEp.Address.ToString());

Client.Close();
Run Code Online (Sandbox Code Playgroud)


Mr *_*ood 7

这是一个无服务器的不同解决方案.我需要让一堆覆盆子在网络上相互了解,但不能保证谁会活跃.所以这种方法可以让每个人都成为客户!完整的库可以在GitHub上找到(免责声明:我创建),这使得整个过程对于UWP应用来说真的很容易.

https://github.com/mattwood2855/WindowsIotDiscovery

此解决方案假设设备名称是唯一的,并且您希望使用JSON字符串作为通信协议,但您可以轻松地发送任何其他格式.此外,在实践中尝试捕捉一切;)

一般机制:

发现你的IpAdress

public string IpAddress
{
    get
    {
        var hosts = NetworkInformation.GetHostNames();
        foreach (var host in hosts)
        {
            if (host.Type == HostNameType.Ipv4) return host.DisplayName;    
        }
        return "";
    }
}
Run Code Online (Sandbox Code Playgroud)

设置你的听众

var udpPort = "1234";
var socket = new DatagramSocket();
socket.MessageReceived += ReceivedDiscoveryMessage;
await socket.BindServiceNameAsync(udpPort);`
Run Code Online (Sandbox Code Playgroud)

处理传入的数据

async void ReceivedDiscoveryMessage(DatagramSocket socket, DatagramSocketMessageReceivedEventArgs args)
{
    // Get the data from the packet
    var result = args.GetDataStream();
    var resultStream = result.AsStreamForRead();
    using (var reader = new StreamReader(resultStream))
    {
        // Load the raw data into a response object
        var potentialRequestString = await reader.ReadToEndAsync(); 
        // Ignore messages from yourself
        if (args.RemoteAddress.DisplayName == IpAddress) return;        
        // Get the message
        JObject jRequest = JObject.Parse(potentialRequestString);
        // Do stuff with the data
    }
}
Run Code Online (Sandbox Code Playgroud)

发送消息

public async void SendDataMessage(string discoveryMessage)
{
    // Get an output stream to all IPs on the given port
    using (var stream = await socket.GetOutputStreamAsync(new HostName("255.255.255.255"), udpPort))
    {
        // Get a data writing stream
        using (var writer = new DataWriter(stream))
        {
            // Write the string to the stream
            writer.WriteString(discoveryMessage);
            // Commit
            await writer.StoreAsync();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

想法是发送包含您的IP地址和名称的发现消息.然后在接收消息功能中将ip-name对添加到设备列表中.添加一点逻辑以避免重复,并在ip更改给定名称时更新IP地址.

作为奖励,您可以让每台设备发送他们了解的设备列表.这允许您通过在发件人意识到您时不响应来最小化udp流量.您甚至可以让接收器将列表与其自己的列表进行比较以发现其他设备.

冗余是您与UDP的朋友,无法保证将传送数据包.