我想为每个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,原因);
我希望你理解它并且可以帮助我:))
谢谢!
答案 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。它不是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,它比轮询套接字更好地工作 。学习使用它,您的代码将更好地工作。