我一直在尝试打孔并将数据报发送到路由器后面的朋友计算机,但没有任何反应

Posted

技术标签:

【中文标题】我一直在尝试打孔并将数据报发送到路由器后面的朋友计算机,但没有任何反应【英文标题】:I have been trying hole punching and send a datagram to my friends computer behind a router but nothing happens 【发布时间】:2013-11-22 11:37:03 【问题描述】:

我正在尝试创建 p2p 连接。这是一个我已经检查过的只是测试应用程序,但它似乎无法通过互联网运行。 这是我在我的电脑上用来向我的朋友发送数据报的 java 代码: '

    import java.io.IOException;
    import java.io.UnsupportedEncodingException;
    import java.net.*;
    import javax.net.ssl.SSLServerSocket;

    public class j2


    public static void main(String[] args) throws Exception 

    InetAddress IPAddress = InetAddress.getByName("my friend's public IP"); 
    DatagramSocket clientSocket = new DatagramSocket(3456);


    System.out.println("Sending data");
    String datamsg = "hello ";
    byte[] sendData = datamsg.getBytes("UTF-8");
    byte [] receiveData = new byte[10];
    DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress,         7890);  

    int i = 500;
    //incase if some packets are lost
    while(i-->1)
    
    clientSocket.send(sendPacket);
    
    System.out.println("Data sent");

    System.out.println(clientSocket.isClosed());

    clientSocket.close();        



    
    

'

    //My friend uses this app to receive a data gram:
    // port 7890 is used to send data gram and create a hole. The same is used to     receice data.

'

    import java.io.IOException;
    import java.io.UnsupportedEncodingException;
    import java.net.*;
    import javax.net.ssl.SSLServerSocket;

    public class j1


    public static void main(String[] args) throws Exception 

    InetAddress IPAddress = InetAddress.getByName("any ip"); //does not matter as it is used to open a hole
    DatagramSocket clientSocket = new DatagramSocket(7890);


    System.out.println("Sending data");
    String datamsg = "hello ";
    byte[] sendData = datamsg.getBytes("UTF-8");
    byte [] receiveData = new byte[10];
    DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, 5000);  

    int i = 500;

    while(i-->1)
    
    clientSocket.send(sendPacket);
    
    System.out.println("Data sent");

    System.out.println(clientSocket.isClosed());



    DatagramPacket receivePacket = new DatagramPacket(sendData, sendData.length);                   

    clientSocket.receive(receivePacket);  

     System.out.println("Packet received");
     String msg = new String(receivePacket.getData());
    clientSocket.close();        

    
    '

    // I am not using a stun server as i already know my friends public ip address. We both have disabled our firewall as well.

【问题讨论】:

显而易见的问题: 1. 如果有,您会遇到什么错误? 2.如果没有错误,你怎么知道它不起作用? 3. 您朋友的路由器是否配置为将这些数据包转发到他的一台计算机? 4. 那台计算机是否正在运行一个进程来接受和/或回复他们? 我的朋友没有收到任何数据包,这就是它没有工作的原因。他正在发送数据包以打开一个洞,以便我可以通过他的路由器发送数据包。 【参考方案1】:

您的方法不是进行 NAT 打孔的最可靠方法。充其量它“有时会起作用”。

以下是一些建议:

不要硬编码端口号。让您的 UDP 套接字代码选择一个随机端口号(即 port=0)并使用 STUN 服务器(或等效服务器)来确定此本地套接字的公共 IP 地址和公共端口映射。

使用可靠的服务来交换 IP/端口。由于您只是试图让一个数据包通过,因此首先使用电话口头交换此信息就足够了。

您不需要一次发送 500 个数据包。防火墙代码 远程 NAT 可能将此视为 DOS 攻击并阻止一切。 尝试每秒发送 1 个。

您应该同时监听和发送周期性数据包 在尝试进行连接检查时,您的代码正在执行。 (例如,两个单独的线程或定期轮询)。

在两个端点都确认连接之前不要关闭套接字。正如您现在所拥有的,您的第一个程序在发送数据包突发后立即关闭套接字。

在此处阅读我的完整答案:https://***.com/a/8524609/104458

【讨论】:

TY 为您的回答...还有一件事@selbie ..我在程序中硬编码的端口号是否被转换为其他端口...因为它的 ip 地址改成我的公网ip??? @RishabhKumar - 大多数 NAT 将尝试使用与内部主机发送的相同外部端口。这并不总是可能的。因此,您应该假设 NAT 为映射地址选择不同的端口号。

以上是关于我一直在尝试打孔并将数据报发送到路由器后面的朋友计算机,但没有任何反应的主要内容,如果未能解决你的问题,请参考以下文章

UDP打孔到期[关闭]

NAT 后面的 UDP 打孔

UDP打孔:无法从服务器发送到客户端

UDP打孔:单机可测试性

向路由器后面的设备发送 HTTP 请求

udp打孔后发送文件