栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

P2P之UDP打洞

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

P2P之UDP打洞

UDP打洞的过程大致如此: 

1、双方都通过UDP与服务器通讯后,网关默认就是做了一个外网IP和端口号 与你内网IP与端口号的映射,这个无需设置的,服务器也不需要知道客户的真正内网IP 

2、用户A先通过服务器知道用户B的外网地址与端口  

3、用户A向用户B的外网地址与端口发送消息,  

4、在这一次发送中,用户B的网关会拒收这条消息,因为它的映射中并没有这条规则。  

5、但是用户A的网关就会增加了一条允许规则,允许接收从B发送过来的消息  

6、服务器要求用户B发送一个消息到用户A的外网IP与端口号  

7、用户B发送一条消息,这时用户A就可以接收到B的消息,而且网关B也增加了允许规则  

8、之后,由于网关A与网关B都增加了允许规则,所以A与B都可以向对方的外网IP和端口号发送消息。

具体代码:

Server:

package ljxwtl.udp;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.nio.charset.StandardCharsets;


public class Server {

    public static void main(String[] args) throws Exception {
        DatagramSocket datagramSocket = new DatagramSocket(8080);
        byte [] buffer = new byte[10240];

        String remoteA = null;
        String remoteB = null;

        int count = 0;
        while (true){
            DatagramPacket datagramPacket = new DatagramPacket(buffer,0,buffer.length);
            datagramSocket.receive(datagramPacket);

            System.out.println("连接成功:"+ datagramPacket.getAddress().getHostAddress() + ":" + datagramPacket.getPort());

            String message = new String(datagramPacket.getData(), 0, datagramPacket.getLength(), StandardCharsets.UTF_8);
            if ("A".equalsIgnoreCase(message)){
                remoteA = datagramPacket.getAddress().getHostAddress() + ":" + datagramPacket.getPort();
                count ++;
            }
            else if ("B".equalsIgnoreCase(message)){
                remoteB = datagramPacket.getAddress().getHostAddress() + ":" + datagramPacket.getPort();
                count ++;
            }
            if (count == 2){
                String[] splitA = remoteA.split(":");
                DatagramPacket datagramPacketA = new DatagramPacket(remoteB.getBytes(StandardCharsets.UTF_8),0,remoteB.length(),InetAddress.getByName(splitA[0]),Integer.parseInt(splitA[1]));
                datagramSocket.send(datagramPacketA);

                String[] splitB = remoteB.split(":");
                DatagramPacket datagramPacketB = new DatagramPacket(remoteA.getBytes(StandardCharsets.UTF_8),0,remoteA.length(),InetAddress.getByName(splitB[0]),Integer.parseInt(splitB[1]));
                datagramSocket.send(datagramPacketB);
            }
        }
    }
}

Client:

package ljxwtl.udp;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.FutureTask;


public class Client {

    public static void main(String[] args) throws Exception {
        DatagramSocket datagramSocket = new DatagramSocket();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
        System.out.println("输入客户端识别码:");
        String clientType = bufferedReader.readLine();
        DatagramPacket datagramPacket = new DatagramPacket(clientType.getBytes(StandardCharsets.UTF_8), 0, clientType.getBytes(StandardCharsets.UTF_8).length, InetAddress.getByName("ljxwtl.cn"), 8080);
        datagramSocket.send(datagramPacket);
        DatagramPacket datagramPacketReceive = new DatagramPacket(new byte[10240],0,10240,InetAddress.getByName("ljxwtl.cn"), 8080);
        datagramSocket.receive(datagramPacketReceive);
        String remoteIPAddresss = new String(datagramPacketReceive.getData(), 0, datagramPacketReceive.getLength());
        System.out.println(remoteIPAddresss);
        String[] splitIpPort = remoteIPAddresss.split(":");
        //发送消息线程
        new Thread(new FutureTask(()->{
            while (true){
                System.out.println("请输入内容:");
                String readLine = bufferedReader.readLine();

                DatagramPacket datagramPacketP2P = new DatagramPacket(readLine.getBytes(StandardCharsets.UTF_8),readLine.getBytes(StandardCharsets.UTF_8).length,InetAddress.getByName(splitIpPort[0]),Integer.parseInt(splitIpPort[1]));
                datagramSocket.send(datagramPacketP2P);
            }
        })).start();

        //接收消息线程
        new Thread(new FutureTask(()->{
            while (true){
                DatagramPacket datagramPacketP2PReceive = new DatagramPacket(new byte[10240],0,10240,InetAddress.getByName(splitIpPort[0]),Integer.parseInt(splitIpPort[1]));

                datagramSocket.receive(datagramPacketP2PReceive);

                System.out.println(new String(datagramPacketP2PReceive.getData(),0,datagramPacketP2PReceive.getLength(), StandardCharsets.UTF_8));

            }
        })).start();
    }
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/781762.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号