UDP 打洞 java demo

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

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值