TCP打孔,不能在android上重用地址

Posted

技术标签:

【中文标题】TCP打孔,不能在android上重用地址【英文标题】:TCP hole punching, can't reuse address on android 【发布时间】:2013-01-25 14:49:14 【问题描述】:

我有一个托管 HTTP 服务器的 android 设备并且是 NATed(在路由器后面)。我想从未经过 NAT 的公共服务器访问它。 我在一个线程中的 8080 端口在 android 设备上运行一个 HTTP 服务器,一段时间后,我启动一个客户端线程,它试图从 android 上的本地端口号 8080 连接到远程公共服务器。 由于某种原因,我在端口 8080 上启动服务器后,android 客户端将无法连接。它也不会产生任何异常。这是我的代码:

Thread server = new Thread(new Runnable() 
public void run() 
    super.run();

    try 
        ServerSocket serverSocket = new ServerSocket();
        serverSocket.setReuseAddress(true);
        serverSocket.bind(new InetSocketAddress("192.168.1.102", 8080));

        while(isRunning)
            try 
                System.out.println("Listening for new connection");
                Socket socket = serverSocket.accept();
                System.out.println("incoming connection accepted");
                new Thread(new ConnectionHandler(socket)).start();    
             catch (IOException e) 
                e.printStackTrace();
                                         
        
        serverSocket.close();
     
    catch (IOException e) 
        e.printStackTrace();
    

);
server.start();



// sleep several seconds before launch of client
Thread.currentThread().sleep(5 * 1000);


Thread client = new Thread(new Runnable() 
public void run() 
    super.run();
    try 
        /* .. */
        Inet4Address localaddr = (Inet4Address) InetAddress
                .getByName("192.168.1.102");
        // Inet4Address remoteaddr = (Inet4Address)
        // InetAddress.getByName("122.176.73.10");
        System.out.println("connecting to 122.176.73.10");

        Socket socket = new Socket();

        socket.setReuseAddress(true);
        System.out.println("[Client]socket.isBound():" + socket.isBound());
        socket.bind(new InetSocketAddress("192.168.1.102", 8080));

        for (int i = 1; i < 5; i++) 
            try 
                socket.connect(new InetSocketAddress("122.176.73.10", 4040));
                System.out.println("connected to 122.176.73.10");
                break;
             catch (Exception e) 
                System.out.println("[Client]fail to connect ");
                Thread.currentThread().sleep(i * 2 * 1000);
            
        
    

);
client.start();

【问题讨论】:

【参考方案1】:

端口号不能同时用于侦听传入连接和建立传出连接。您在8080 上的侦听套接字会阻止使用该端口的任何其他操作。

【讨论】:

据称在这里工作:ramonli.blogspot.in/2012/03/…

以上是关于TCP打孔,不能在android上重用地址的主要内容,如果未能解决你的问题,请参考以下文章

为啥这种方式的 TCP 打孔不起作用?

无法使用 STUN 执行 TCP 打孔

UPnP打孔不能使用外部IP访问本地子网上的设备

TODO:Golang语言TCP/UDP协议重用地址端口

移动提供商无法进行 UDP 打孔

TCP 打孔 Java 示例