C# 从服务器连接Lidgren中的对等方

C# 从服务器连接Lidgren中的对等方,c#,networking,p2p,lidgren,C#,Networking,P2p,Lidgren,我想建立一个P2P配对服务器。情况如下: 我在NAT路由器后面有2个以上的节点 我在静态IP上的端口转发路由器后面有一台服务器 服务器的任务是注册每个对等方的联系信息,并在请求时将其发送给任何其他对等方 然后,对等方可以在服务器上查询其他方的列表,并直接连接到它们 目前,对等方可以连接到服务器,注册他们的地址,并查询其他对等方的地址。我的问题是介绍同龄人 我目前得到的内部和外部IP地址的每一个对等像这样。它主要基于Lidgren附带的主服务器示例;然而,这只是将用户连接到客户机/服务器会话,

我想建立一个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打孔正常工作所需的一切,但我缺乏实现这一目标的利德格伦知识

最后,以下是我如何设置我的peer_客户端:

//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();

您是否使用“config.EnableMessageType(NetIncomingMessageType.natintProductionSuccess);”启用了介绍消息

“14243”是打字错误吗?在示例中,主服务器侦听14343,客户端侦听14242

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


记住IPEndPoint包含端口号,如果您将其存储在某个地方,您可能需要将其设置为您试图打开的端口

我确实尝试在对等连接上启用消息,但似乎没有任何效果。14243确实是正确的。我转发了两个端口,只选择了一个。我有一个用于连接到服务器的NetClient,还有一个用于(理想情况下)连接到对等点的NetPeer。即使我正在共享NetPeer的iEndpoints,NetClient也会接收NAT消息。现在我想到了这一点,我想知道服务器在发送请求消息时是否正在接收NetClient的外部IP。。。我将考虑使用相同的NetPeer与服务器联系,并放弃单独的NetClient。