我怎样才能让每个客户端都知道连接到同一个 UDP 网络的每个其他客户端?

How can I make every client be aware of every other client connected to the same UDP network?

我希望每个客户端 'be aware of' 应请求在 UDP 网络内连接的所有其他客户端。

到目前为止,我有一个非常简单的程序,其中每个客户端输入用户名并将其发送到网络。每个客户端都存储一个用户名列表,以跟踪谁至少与网络通信过一次。如果弹出一个新的用户名,它会将其输出到控制台并将其存储在列表中以防止再次输出。

这一切都很好,但我只是通过让每个客户端不断等待来自网络的新数据来管理上述内容(因为它永远不知道新客户端何时会停止 'entering' 网络)。

这是所有代码。感兴趣的部分可能是 displayAllUsers() 函数。

我粘贴了整个程序,因为它 (i) 很短 (ii) 我对 C# 中的 UDP 的了解很新,而且我的实践一点也不好,所以也许是个好主意让读者知道这一点。

using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace Node
{
    class Program
    {

        static UdpClient client = new UdpClient();
        static IPEndPoint localIP;
        static IPEndPoint remoteIP;

        static String currentUser;
        static List<String> currentUsers = new List<String>();

        static void Main(string[] args)
        {

            initialiseListener();
            initialiseWriter();

            Console.WriteLine("What's your username?");
            currentUser = Console.ReadLine();
            Byte[] buffer = Encoding.Unicode.GetBytes(currentUser);
            //Who is current user?

            client.Send(buffer, buffer.Length, remoteIP);

            Console.WriteLine("Here are all active users:");


            displayAllUsers();


        }

        private static void displayAllUsers()
        {
            Byte[] buffer;

            while (true)
            {


                Byte[] data = client.Receive(ref localIP); //blocking call - continuously listening 
                string strData = Encoding.Unicode.GetString(data);


                if (!currentUsers.Contains(strData)) //if data is not found in current users list...
                {
                    Console.WriteLine(strData); //write username on screen
                    currentUsers.Add(strData); //and add to current users list

                    buffer = Encoding.Unicode.GetBytes(currentUser); //Convert currentUser to bytes
                    client.Send(buffer, buffer.Length, remoteIP); //and send new current user to everyone else
                }


            }

        }

        private static void initialiseWriter()
        {
            IPAddress multicastAddress = IPAddress.Parse("239.0.0.222");
            client.JoinMulticastGroup(multicastAddress);
            //Send data to this multicast address group

            remoteIP = new IPEndPoint(multicastAddress, 2222); //To write to the multicastAddress group on port 2222
        }

        private static void initialiseListener()
        {
            client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            client.ExclusiveAddressUse = false;
            //More than one client can use the port to be specified

            localIP = new IPEndPoint(IPAddress.Any, 2222); //To listen on any IP Address available from the port 2222

            client.Client.Bind(localIP); //Associate client with listener
        }
    }
}

理想情况下,每个客户端都能够在任何时候请求 displayAllUsers() 设备并为他们生成这样的列表,而不是不断地等待新客户端加入。

最终,我想将我对 UDP 和非集中式网络的了解应用到 Xamarin 应用程序中,并让每台设备都知道打开此类应用程序的所有其他设备。

我从 here 找到了一个解决方案,并在我的 displayAllUsers() 方法中修改了以下内容。

if(client.Available > 0){
   data = client.Receive(ref localIP); //blocking call - continuously listening 
}else{
   break;
}

事实证明,使用 .Available 属性 非常有用,因为它会检查是否有东西可以听——正是我需要的。

如果认为这是好的做法,我会将其标记为主题的答案。