从服务器连接Lidgren中的对等体

本文关键字:对等 Lidgren 服务器 连接 | 更新日期: 2023-09-27 18:13:29

我想建立一个P2P婚介服务器。情况如下:

  • 我在NAT路由器后面有2+对等体。
  • 我有一个服务器在静态IP的端口转发路由器后面。
  • 服务器的工作是注册每个对等体的联系信息,并在请求时发送给任何其他对等体。
  • 对等体可以向服务器查询其他列表,并直接连接到它们。

目前,对等体可以连接到服务器,注册自己的地址,并查询其他对等体的地址。我的问题是把同学们介绍给彼此。

我目前正在获得每个对等体的内部和外部IP地址。它在很大程度上是基于主服务器样本,与Lidgren;然而,这只是将用户连接到客户端/服务器会话,而我需要点对点。

//client code; getting our internal IP and sending it to the server
NetOutgoingMessage om = server_client.CreateMessage(); //create message on the server's connection
... //header
IPAddress mask;
var endpoint = new IPEndPoint(NetUtility.GetMyAddress(out mask), peer_client.Port); //gets the internal IP address
... //write message data and send to server

当服务器收到请求时,或者当一个对等体注册到服务器时,它从连接消息中获得该对等体的外部IP。然后,在处理请求时,我们可以从两个对等端访问两个ip:

//server code, handling the peer request message:
...
string key = msg.ReadString();
Output("Requesting peer: " + key);
IPEndPoint requester_internal = msg.ReadIPEndPoint();
IPEndPoint requester_external = msg.SenderEndPoint;
//attempt to find requested user
User u = null;
if (Users.TryGetValue(id, out u))
{
    IPEndPoint target_internal = u.IPInternal;
    IPEndPoint target_external = u.IPExternal;
    ...
    //send the requested IPs to the sender, and the sender's IPs to the target.
}

现在,问题是如何使用此信息(或建立连接所需的任何其他信息)将对等点彼此连接起来,因为其他基础设施已经正常工作。

我的第一个尝试是使用内置的介绍方法:

//server code, continuing from the above
//instead of directly sending IPs to users, introduce them ourselves
s_server.Introduce(target_internal, target_external, requester_internal, requester_external, key);

这似乎在某种程度上工作,但它连接到每个客户端的服务器连接,而不是对等端连接,并且只在发送方成功。

尝试手动连接已发送的ip导致无尽的"尝试连接"消息:

//peer code; handling 'other peer data received' msg
IPEndPoint peer_internal = msg.ReadIPEndPoint();
IPEndPoint peer_external = msg.ReadIPEndPoint();
Output("SERVER: Recieved peer IP. Attempting to connect to:'n" + peer_internal.ToString() + "'n" + peer_external.ToString());
NetOutgoingMessage om = peer_client.CreateMessage();
om.Write((Int32)3); //unique header for debugging purposes
peer_client.Connect(peer_external, om); //tried both internal and external, no dice

最后,我看到的ip示例,从服务器转储:

P1 Internal: 169.xxx.xxx.xxx:14243 //local subnet address, using the proper port
P1 External: xxx.xxx.xxx.xxx:62105 //IP address of the system, matching that from any IP testing site, but using a seemingly random port
P2 Internal: 169.xxx.xxx.xxx:14243 //same as above for the second peer
P2 External: xxx.xxx.xxx.xxx:62106

我认为问题是对等连接的外部端口是随机创建的,而不是使用我在创建时指定的端口。因此,不能提前转发。我很高兴用户被要求转发一个特定的端口,因为许多P2P游戏都是这样做的。

换句话说,我似乎拥有了使NAT冲压正常工作所需的一切,但我缺乏Lidgren的知识来实现它。

最后,下面是我如何设置我的peer_client:

//peer code: initialize the connection to any other peers we may connect to later
NetPeerConfiguration pconfig = new NetPeerConfiguration(appidstr_client);
pconfig.Port = 14243; //properly forwarded in router
pconfig.EnableMessageType(NetIncomingMessageType.DiscoveryRequest);
pconfig.SetMessageTypeEnabled(NetIncomingMessageType.UnconnectedData, true);
pconfig.AcceptIncomingConnections = true;
peer_client = new NetPeer(pconfig);
peer_client.Start();

从服务器连接Lidgren中的对等体

是否使用"config.EnableMessageType(netincomingmessagetype . natintrotionsuccess);"启用介绍消息?

"14243"是一个错字吗?在示例中,主服务器监听14343,客户端监听14242。

"这似乎在某种程度上工作,但它连接到每个客户端的服务器连接,而不是对等端连接,并且只在发送端成功。"我不明白这是什么意思。如果你使用NetPeer类,没有特定的"服务器连接"?

记住IPEndPoint包含端口号,以防您将它存储在某个地方,您可能希望将其设置为您试图打开的端口。