【发布时间】:2015-02-28 01:38:50
【问题描述】:
我之前使用 UDP 打孔制作了一个简单的点对点聊天程序,该程序有效,现在我正在尝试在使用 libGDX 制作的游戏中做类似的事情。游戏本身运行良好,连接在 LAN 上工作,但我很难尝试使用外部连接。我了解 UDP 打孔的工作原理如下:
如果 A 和 B 都知道对方的 IP 地址和端口,那么:
- A 向 B 发送一个 UDP 数据包,该数据包在 A 的 NAT 上打了一个洞,但被 B 的防火墙丢弃
- A 等待回复
- B 向 A 发送一个 UDP 数据包,该数据包在其自己的 NAT 上打了一个洞并通过 A 的防火墙
- B 等待回复
- A 收到 B 的初始消息并向 B 发送第二条消息
- B 收到 A 的消息
我的网络代码属于一类:
private boolean connected;
private DatagramSocket socket;
private DatagramPacket packet;
private InetAddress peerIP;
public NetworkManager(InetAddress peerIP){
this.peerIP = peerIP;
log("Created with peer ip: " + peerIP.getHostAddress());
connected = false;
}
@Override
public void run(){
try{
log("Setting up socket");
socket = new DatagramSocket(Constants.CLIENT_PORT);
log("Socket successfully setup");
//Punch hole
log("Punching UDP Hole");
sendBytes("one");
//Receive
log("Waiting for peer reply");
receiveBytes(3);
//Send second message
if(Arrays.equals(packet.getData(), "one".getBytes()) ){
sendBytes("two");
}
}catch(Exception e){
log("Error connecting to peer");
return;
}
log("Successfully connected");
connected = true;
}
private synchronized void receiveBytes(int length) throws Exception {
packet = new DatagramPacket(new byte[length], length);
log("Receiving " + length + " bytes...");
socket.receive(packet);
log("Received bytes " + packet.getData()+ " from " + packet.getAddress());
}
private synchronized void sendBytes(String s) throws Exception {
byte[] sendBytes = s.getBytes();
packet = new DatagramPacket(sendBytes, sendBytes.length, peerIP, Constants.CLIENT_PORT);
log("Sending " + sendBytes.length + " bytes...");
socket.send(packet);
log("Bytes sent");
}
【问题讨论】:
-
“我很难尝试外部连接。”。不要让我们猜测。什么不工作>?您尝试过什么来解决这些问题?
-
我曾尝试让一些朋友运行该程序,但即使我尝试手动发送数据包,打孔似乎也无法正常工作
-
“不能正常工作”是什么意思?基本上,您只是在说“它不起作用”,但没有给我们任何关于它不起作用的线索。可以手动配置路由器以让数据包通过吗?然后你的程序有效吗?有消息通过吗?
-
我没有尝试手动配置它们,但我知道数据包正在发送,它们很可能被对等方的防火墙丢弃。我假设我如何解释 UDP 打孔存在错误。我之前实现的几乎完全相同,但是对于一个有效的简单聊天程序,所以我仍然不明白哪里出了问题。
-
请给我们一些信息 - 否则我们只是猜测。除非有更多信息,否则我不会再回复了。您需要帮助我们来帮助您。
标签: java networking udp hole-punching