Android: NAT Traversal?

后端 未结 4 1740
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-15 10:23

It appears to me that newer Android devices run behind a NAT, where the local address is an internal carrier or LAN address and the public address is the router or carrier a

4条回答
  •  执笔经年
    2020-12-15 11:06

    I do that in my own project and have found this issue is not that complicated.

    Here's a very simple UDP echo server in node.js

    var dgram = require('dgram');
    
    var socket =
        dgram.createSocket('udp4');
    
    socket
        .on('listening', function()
        {
            var address = socket.address();
            console.log('socket listening ' +
                address.address + ':' + address.port);
        })
        .on('error', function(err)
        {
            console.log('socket error:\n' + err.stack);
            socket.close();
        })
        .on('message', function(message, rinfo)
        {
            console.log('message: ' + message + ' from ' +
                rinfo.address + ':' + rinfo.port);
    
            var msg = new Buffer(rinfo.address + ':' + rinfo.port);
            socket
                .send(msg, 0, msg.length,
                    rinfo.port, rinfo.address,
                    function(err, bytes)
                    {
                        //socket.close();
                    });
    
        })
        .bind(15000);
    

    An android client simply send a msg to this node server

    System.out.println("UDP hole punching=======================");
    
    class IOth extends Thread {
        @Override
        public void run() {
    
            String sendMsg = "UDP hole punching";
            byte[] buf = sendMsg.getBytes();
            DatagramPacket packet;
    
            System.out.println(HPremoteHost); // node server IP
            System.out.println(HPremotePort); // 15000
            try {
                packet = new DatagramPacket(buf, buf.length, InetAddress.getByName(HPremoteHost), HPremotePort);
                ds.send(packet);
            } catch (Exception e) {
                System.out.println("error================");
                System.out.println(e);
            }
        }
    }
    IOth io00 = new IOth();
    io00.start();
    

    Android Client UDP listener to obtain general msg and your own Global ip&port via UDPholepunching

    class IOLoop extends Thread {
        @Override
        public void run() {
            try {
                String msg = "Native.UDPserver.open";
                SocketAddress sockAddress;
                String address;
                byte[] buf = new byte[1024];
                DatagramPacket packet = new DatagramPacket(buf, buf.length);
                while (true) {
                    try {
                        ds.receive(packet);
                        sockAddress = packet.getSocketAddress();
                        address = sockAddress.toString();
    
                        msg = new String(buf, 0, packet.getLength());
    
                        System.out.println(msg + "  received !!! by " + address);
    
                        // this case is UDP HolePunching reaction
                        if (address.equals(HPaddress1)) {
                            System.out.println(msg + "hole punched");
    
                            // So you can obtain own Global ip& port here.
                            // exchange this information
                            // `remoteHost` `remotePort` to another client
                            // with some method (signaling server)
                        }
                    } catch (IOException e) {
                    }
                }
            } catch (Exception e) {
            }
        }
    }
    IOLoop io00 = new IOLoop();
    io00.start();
    

    Android Client UDP sender using other client's IP remoteHost remotePort

    class IOth extends Thread {
        @Override
        public void run() {
            String sendMsg = "This is a test message";
            byte[] buf = sendMsg.getBytes();
            DatagramPacket packet;
    
            try {
                packet = new DatagramPacket(buf, buf.length, InetAddress.getByName(remoteHost), remotePort);
                ds.send(packet);
            } catch (Exception e) {
            }
        }
    }
    IOth io00 = new IOth();
    io00.start();
    

提交回复
热议问题