2012-03-02 104 views
0

我目前正在编写一个允许客户端登录的UDP应用程序。之后,他们的端点被存储在一个列表中。UDP和端口随机化

private void socket_Callback(IAsyncResult result_) 
{ 
    EndPoint remote = new IPEndPoint(IPAddress.Any, 0); 
    socket.EndReceiveFrom(result_, ref remote); 

    if (!listOfEndPoints.Contains(remote)) 
    { 
     // registration process 

     // add it to list 
     listOfEndPoints.Add(remote) 
    } 
    else 
    { 
     // process packet 
    } 
} 

但是,有时客户端的NAT会为每个数据包分配一个不同的外部端点。如果注册分组的源端点是12.34.56.78:1000,则该端点将被添加到列表中。然而,如果同一个客户端发送另一个数据包,NAT将为它分配一个不同的端口,所以它的源端点将是12.34.56.78:1001。 这会导致服务器假定客户端未注册并尝试将该数据包作为注册处理。不用说这是行不通的。

解决这个问题的一种方法是发送一个ID(如果它不是超级神秘的话,它很容易伪造)给客户端。但是,客户端必须将其添加到发送到服务器的每个数据包中。 因此,这样做并不是非常有效。

是否有任何其他方式告诉数据包与注册数据包来自同一个客户端?

回答

3

您应该肯定使用而不是使用UDP数据包的源IP地址和端口将其与逻辑连接相关联。如果您收到同一逻辑连接的新IP和端口,则应在每个数据包中包含连接的ID并更新您响应的IP和端口。如果连接hi-jacking存在问题,则可能需要实现某种形式的安全性,例如数据报中的安全校验和。

TCP处理将数据包与连接关联起来。使用UDP,您必须自己将数据报与逻辑会话相关联。我不知道你为什么认为“这样做不会很有效”。

UDP的一个折衷是,如果你需要TCP提供的任何东西,你必须自己编写代码。

顺便说一下,我从来没有见过这样的港口转移。你确定客户端代码没有损坏,可能为它发送的每个数据报打开一个新的套接字。

+0

谢谢!如果这是我的代码中的一个错误,为什么我不应该使用数据包的终点?那么对于每个客户来说,这不是唯一的吗?那么安全校验和会是什么样子?我正在考虑在客户注册时向客户发送一个随机数字。客户端然后将md5(分组数据异或校验和)添加到分组。然后服务器将检查校验和的正确性。那是你的意思吗? – haiyyu 2012-03-02 13:28:21

+1

@haiyyu:不使用端点数据的原因是因为另一端的IP地址可能会改变。通过TCP,可以理解网络需要将数据包与会话相关联,并且NAT设备知道要保留这些IP。使用UDP,他们不会。是的,这就是我的意思。最好的解决方案当然取决于你的要求。 – 2012-03-02 13:42:21