Android UDP内网连接外网服务器

来源:互联网 发布:淘宝达人大v认证难不难 编辑:程序博客网 时间:2024/04/29 23:21

最近项目中遇到要求使用UDP做连接, 以前只做过TCP,一直以为UDP不能进行内外网通信。

困扰很久,终于在网上经过一番搜索,搞明白了打洞是怎么回事了 :

据我愚见,打洞就是当内网机器A(192.168.0.2,211.11.11.11)发送一条消息到外网机器B(211.22.22.22)时,数据通过A所在的路由器时,路由器会记录数据的发送者的地址和端口,和数据接受者的地址和端口,并分配一个端口用来转发数据。当下次数据从B的相同端口发到这个分配的端口上时,路由器会直接转发给之前记录的内网机器A,这样就完成了打洞。

也就是说这种方法至少有一端是外网,和tcp一样,但是两端都是内网时,还是需要一个外网机器来充当打洞者,为两端打洞,具体方法,我也不清楚了。

下面看看UDP实现的代码:

 

    public static DatagramSocket DATA_SOCKET;   /**     * 自動尋找一個可用端口     * @param port     */    public static boolean BondPort(int port) {        try {            DATA_SOCKET = new DatagramSocket(port);            ReceiveThread().start();            return true;        } catch (SocketException e) {            // TODO Auto-generated catch block            if (PORT >= 65535) return false;            e.printStackTrace();            return BondPort(++PORT);        }    }

 通过这样的方法就能创建好UDP的socket。

但是收发数据不再象TCP一样建个流就可以了 ,  我们需要定义一个DatagramPacket 用来收发数据,

接收数据和发送数据的DatagramPacket 定义略有不同的:

    /**     * 发送数据     * @param buff     * @return     */    public static int Send(byte[] buff) {        try {            DatagramPacket dataPacket = new DatagramPacket(buff, buff.length, InetAddress.getByName(SERVER_IP), PORT);            DATA_SOCKET.send(dataPacket);        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }        return 0;    }

 

    /**     * 接收数据的线程     * 接收到数据后由DataProcess分发到各个模块     * @return     */    public static Thread ReceiveThread() {        return new Thread() {            @Override            public void run() {                byte[] receiveByte = new byte[512]; // 大小根据需求定义                DatagramPacket dataPacket = new DatagramPacket(receiveByte, receiveByte.length);                while (true)// 无数据,则循环                {                    try {                        DATA_SOCKET.receive(dataPacket); // 接收数据                        if (dataPacket.getLength() > 0) {                            ServerProcess.Process(receiveByte);                        }                    } catch (IOException e) {                        // TODO Auto-generated catch block                        e.printStackTrace();                    }                }            }        };    } 
原创粉丝点击