欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

UDP 打洞 java demo

程序员文章站 2022-06-28 16:13:54
UDP打洞的具体原理就不细说了文章还是很多,说下我的网络环境,家里台式电脑网线连的家里路由器(移动宽带),公司台式电脑网线连的公司路由器(电信宽带),一台有公网IP的华为云主机(我是试用一个月的)1、华为云主机UDPServer代码import java.io.IOException;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetAddress;import java.util....

UDP打洞的具体原理就不细说了文章还是很多,说下我的网络环境,家里台式电脑网线连的家里路由器(移动宽带),公司台式电脑网线连的公司路由器(电信宽带),一台有公网IP的华为云主机(我是试用一个月的)
1、华为云主机UDPServer代码

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.LinkedHashMap;

public class UDPServer {
    private static ArrayList<String> c = new ArrayList<String>();
    public static void main(String[] args) throws IOException, InterruptedException {
        DatagramSocket server = new DatagramSocket(9999);
        byte[] bytes = new byte[1024];
        while (true) {
            DatagramPacket packet = new DatagramPacket(bytes, bytes.length);
            server.receive(packet);
            InetAddress address = packet.getAddress();
            int port = packet.getPort();
            String s = address.getHostAddress()+":"+port;
            System.out.println("收到->"+s+"的消息:");

            if (!c.contains(s)){
                c.add(s);
            }

            for (String s1 : c) {
                if (!s1.equals(s)){
                    byte[] b = ("this is server:"+s1).getBytes();
                    DatagramPacket packet1 = new DatagramPacket(b, b.length, address,port);
                    server.send(packet1);
                }
            }
        }
    }
}

2、公司台式电脑的UDPClient端代码

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.concurrent.TimeUnit;

public class UDPClient {
    private static final ArrayList<String> c = new ArrayList<String>();
    private static boolean b=true;
    public static void main(String[] args) throws IOException, InterruptedException {
        DatagramSocket socket = new DatagramSocket();
        new Thread(()->{
            try {
                byte[] bytes = new byte[1024];
                DatagramPacket packet1 = new DatagramPacket(bytes, bytes.length);
                while (true){
                    socket.receive(packet1);
                    String receive = new String(bytes,0,packet1.getLength());
                    if (receive.contains("server")){
                        c.add(receive);
                    }
                    if (receive.contains("client")){
                        b = false;
                    }
                    System.out.println(receive);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();

        byte[] data1 = "client:my is company".getBytes();
        while (true){
            if (b) {
                DatagramPacket packet1 = new DatagramPacket(data1, data1.length, InetAddress.getByName("121.36.221.82"),9999);
                socket.send(packet1);
            }
            if (!c.isEmpty()){
                DatagramPacket packet2 = new DatagramPacket(data1, data1.length, InetAddress.getByName(c.get(0).split(":")[1]), Integer.parseInt(c.get(0).split(":")[2]));
                socket.send(packet2);
            }
            TimeUnit.SECONDS.sleep(2);
        }
    }
}

3、家里的台电机和UDPClient的代码一样,修改sleep的时间为1秒,为了区分客户端发送的消息company可以改为family。121.36.21.88是我的华为云主机公网IP,代码也没有什么逻辑就没写注释,先启动Server,再启动两个客户端代码,如果客户端不停打印出my is company的提示说明打洞成功。成功后客户端不会再给Server发送消息,后面再贴Android的demo

本文地址:https://blog.csdn.net/Erwinl/article/details/112271479