【问题标题】:List of clients connected to Udp Server in C#在 C# 中连接到 Udp 服务器的客户端列表
【发布时间】:2019-11-01 14:03:51
【问题描述】:

我有一个适用于 Udp 的套接字程序。

我想管理连接到服务器的客户端。

例如,如果客户端连接到服务器,则将该客户端添加到列表中。 我已经使用以下代码在 Tcp 中完成了此操作:

static readonly Dictionary <int, TcpClient> list_clients = new Dictionary <int, TcpClient>();

例如,只有在列表中的客户,他的消息才会被写入。

我将每个客户与GetStream() 进行了比较。但在 Udp 中我不知道该怎么做。我可以管理客户吗?

编辑

我使用以下代码接收来自客户端的消息:

private static UdpClient udpServer = new UdpClient(11000);
private static IPEndPoint remoteEP = new IPEndPoint(IPAddress.Any, 11000);

static void Main(string[] args)
{
    var firstData = udpServer.Receive(ref remoteEP);
    Console.WriteLine(Encoding.ASCII.GetString(firtsData);
}

提前致谢

【问题讨论】:

  • UDP 是无连接的。您当然可以保留客户端列表,但您必须手动跟踪哪些客户端正在主动发送消息,以及哪些客户端在 X 时间内没有发送任何消息(和/或收到回复),以便您可以将它们从列表。
  • 客户有哪些具体特点可以相互区分?在 Tcp 中,它们的流不同,可以通过 GetStream 获得。 @remy-lebeau
  • 由于UDP中没有流,可以通过远程IPEndPoint来区分。否则,让您的 UDP 消息在其有效负载数据中携带客户标识,例如用户 ID、唯一会话 cookie 等。
  • (remote IP: port) 对我来说在 UDP 中总是一样的。我之前唯一想到的,你也提到过,就是在消息中放一个 id 或一定数量。
  • "remoteEP 数据总是不同的吗?" - 如果您有多个客户端发送到您的服务器,那么可以。它代表刚刚读取的当前数据包的远程端点。因此,如果您一次从多个客户端获取数据包,remoteEP 将根据需要在它们之间切换

标签: c# .net sockets udp client


【解决方案1】:

这段代码很适合我!
服务器:

    public partial class Server : Form
    {
        public Server()
        {
            InitializeComponent();
        }

        void Print(string message)
        {
            listBox1.Items.Add(message);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            socket.Bind(new IPEndPoint(IPAddress.Loopback, 55555));
            byte[] vs = new byte[100];
            EndPoint senderRemote = new IPEndPoint(IPAddress.Any, 0);

            Dictionary<EndPoint, int> pairs = new Dictionary<EndPoint, int>();
            int id = 0;
            for (int ii = 0; ii < 5; ii++)
            {
                socket.ReceiveFrom(vs, ref senderRemote);
                if (pairs.ContainsKey(senderRemote))
                    Print(pairs[senderRemote].ToString() + " says:");
                else
                {
                    pairs.Add(senderRemote, id++);
                    Print("new sender");
                }
                Print(senderRemote.ToString());
                Print(Encoding.Unicode.GetString(vs));
                socket.SendTo(vs, senderRemote);
            }

        }
    }

客户:

    public partial class Client : Form
    {
        public Client()
        {
            InitializeComponent();
        }
        Socket socket;
        private void button1_Click(object sender, EventArgs e)
        {
            socket.Send(Encoding.Unicode.GetBytes("Gholamam!"));
            byte[] vs = new byte[100];
            socket.Receive(vs);
            listBox1.Items.Add(Encoding.Unicode.GetString(vs));
        }

        private void Client_Load(object sender, EventArgs e)
        {
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            socket.Bind(new IPEndPoint(IPAddress.Loopback, new Random().Next(1024,65000)));
            socket.Connect(IPAddress.Loopback, 55555);
        }
    }

不要忘记客户端和服务器正在通信。因此他们必须使用妥协的方式进行交流。如果你喜欢存储客户信息,它必须是常量。为此,您必须将bind 设置为固定的localEndPoint
您还可以使用问题 cmets 中的解决方案:您可以在消息中添加 id。你也可以同时使用。
P.S.:我使用 Socket Class 而不是 TCPClientUDPClient 因为我发现它们在某些方面很尴尬和不一致。

【讨论】:

    猜你喜欢
    • 2016-02-16
    • 2012-03-27
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 2023-04-09
    • 2013-05-18
    • 1970-01-01
    相关资源
    最近更新 更多