C#TCP - 如何设置套接字ID?

时间:2017-03-14 06:34:08

标签: c# sockets tcp

我想为每个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,原因);

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(ID,原因);

我希望你理解它并且可以帮助我:))

谢谢!

1 个答案:

答案 0 :(得分:0)

  

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

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

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

出于安全原因,如果客户端ID以能够预测客户端ID不好的方式暴露给潜在的攻击者,则这是一个糟糕的选择。但在许多情况下,这并不重要。

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

  

无法获取OnPlayerDisconnectFromTCP的ID(ID,原因);

如果是这样,那是因为你错误地使用了API。它不是AsyncStateSocket本身,而应该是描述客户端的数据结构,其中包括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,它比轮询套接字更好地工作 。学习使用它,您的代码将更好地工作。