UDP和端口随机化

时间:2012-03-02 13:17:44

标签: c# sockets udp nat

我正在编写一个允许客户端登录的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(如果它不是超级神秘的话,可以很容易地伪造)。但是,客户端必须将其添加到它发送到服务器的每个数据包中。 所以这样做是不太有效的。

有没有其他方法可以告知数据包来自与注册数据包相同的客户端?

1 个答案:

答案 0 :(得分:3)

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

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

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

顺便说一句,我从未见过以这种方式移动的端口。您确定客户端代码没有损坏,可能会为它发送的每个数据报打开一个新的套接字。