【问题标题】:C# TCP - How to set a ID to a socket?C# TCP - 如何为套接字设置 ID?
【发布时间】:2017-03-14 15:19:04
【问题描述】:

我想为每个 Socket 设置一个 ID。

目前我有这个:

Socket socket;
            try{socket = serverSocket.EndAccept(AR);}
            catch (ArgumentException e) { WriteConsoleColor(new ColoredString(ConsoleColor.Red, "[ERROR] " + e));return; }
            clientSockets.Add(socket);
            socket.BeginReceive(buffer, 0, BUFFER_SIZE, SocketFlags.None, ReceiveCallback, socket);
            serverSocket.BeginAccept(AcceptCallback, null);
            login_script.OnPlayerConnectToTCP(clientSockets.Count);

我使用 clientSockets.Count 设置 ID,但我认为 不是设置 ID 的最佳方式。

我也有一个OnPlayerDisconnectFromTCP(ID,reason);

Socket current = (Socket)AR.AsyncState;            
if (current.Poll(0, SelectMode.SelectRead)){
                if (current.Receive(recBuf, SocketFlags.Peek) == 0){
                    login_script.OnPlayerDisconnectFromTCP(0, "Leave");
                    return;
                }
            }else { WriteConsoleColor(new ColoredString(ConsoleColor.Red, String.Format("[Invalid Packet] User(ID:{0}) send a invalid Packet ({1})\n", "test", Packet))); }

问题是没有办法获取 OnPlayerDisconnectFromTCP(ID,reason);

的 ID

希望你能理解并帮助我:)

谢谢!

【问题讨论】:

    标签: c# sockets tcp


    【解决方案1】:

    我使用 clientSockets.Count 设置了一个 ID,但我认为这不是设置 ID 的最佳方式

    可能不会。毕竟,如果一个客户端连接(ID 为 1),第二个客户端连接(ID 为 2),第一个客户端断开连接,然后第三个客户端连接(ID 为 2,即使您的第二个客户端 ID 为 2,会发生什么情况仍然连接)。这似乎是一个糟糕的选择。 :)

    根据您的需要,保留一个计数器(而不是集合的计数)可能就足够了,您可以随每个新客户端递增。使用int,您可以通过这种方式处理 40 亿客户,而无需担心重复的客户 ID。假设这实际上是一个问题,解决起来并不难。您可以选择使用long 代替(在环绕之前为您提供大约 18 个 quintillion 客户端),或者当您使用 int 一路回到 0 时,借此机会重新分配客户端 ID对于所有当前连接的客户端,再次以0 开头。

    出于安全原因,如果客户端 ID 以无法预测客户端 ID 的方式暴露给潜在攻击者,这是一个糟糕的选择。但在很多情况下,这无关紧要。

    如果您需要降低 ID 的可预测性,还有其他技术。例如,使用Guid.NewGuid()

    没有办法获取 OnPlayerDisconnectFromTCP(ID,reason) 的 ID;

    如果是这样,那是因为您使用了错误的 API。而不是AsyncState 值是Socket 本身,它应该是一个描述您的客户的数据结构,其中包括Socket 参考和客户ID 或您想要包含或需要的任何其他识别信息。

    这样,当您完成 I/O 操作时,您会使用客户端信息的完整上下文,包括您需要传递给方法的任何 ID。

    相关讨论另见How to identify clients from a pool of clients in the server - Design


    只要我在写作,我也会强烈建议您改掉使用Poll()SocketFlags.Peek 之类的东西的习惯。 .NET 为 I/O 提供了一个非常有用且可扩展的异步 API,它的工作原理比轮询套接字要好得多。学会使用它,你的代码就会工作得更好。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-16
    • 2014-12-31
    • 1970-01-01
    • 2012-12-22
    • 2017-01-21
    相关资源
    最近更新 更多