3

我有一个设置,其中 2 台电脑(假设 A 和 B)位于每个公共 IP 的 NAT 后面。所以他们每个人都有自己不同的私有IP。我在两者之间使用了一个服务器,它将交换 IP 地址和端口号。A和B的。他们还交换了他们的内部端口号..!

在此处输入图像描述

所以基本上这就是设置。

客户端 A 和 B 运行以下代码:

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class Clientnew {

     public static void main(String[] args) throws Exception {
    // prepare Socket
    DatagramSocket clientSocket = new DatagramSocket();

    for(int i = 1;i<10;i++){
    // prepare Data
    byte[] sendData = "Hello".getBytes();
    // send Data to Serverc
    DatagramPacket sendPacket = new DatagramPacket(sendData,
            sendData.length, InetAddress.getByName("27.251.62.27"), 7070);
    clientSocket.send(sendPacket);

    //send localip and local port to server
         System.out.println("Sending Local info");
//   InetAddress IPAddressLocal = clientSocket.getLocalAddress();
   int PortLocal = clientSocket.getLocalPort();
        String msgInfoOfClient1 = PortLocal+":PortLocal";

        byte[] newData = msgInfoOfClient1.getBytes();
         System.out.println(msgInfoOfClient1);
        DatagramPacket sendLocalPacket = new DatagramPacket(newData, newData.length, InetAddress.getByName("27.251.62.27"), 7070);
        clientSocket.send(sendLocalPacket);

     // receive External Data ==> Format:"<External IP of other Client>-<External Port of other Client>"
    DatagramPacket receivePacket = new DatagramPacket(new byte[1024], 1024);
    clientSocket.receive(receivePacket);

    // Convert Response to IP and Port
    String response = new String(receivePacket.getData());
    String[] splitResponse = response.split("-");
    InetAddress External_IP = InetAddress.getByName(splitResponse[0].substring(1));

    int External_Port = Integer.parseInt(splitResponse[1]);

    // output converted Data for check
    System.out.println("External IP: " + External_IP + " External PORT: " + External_Port);   


    // receive Internal Data ==> Format:"<Internal IP of other Client>-<Internal Port of other Client>"
    DatagramPacket anotherPacket = new DatagramPacket(new byte[1024], 1024);
    clientSocket.receive(anotherPacket);

    // Convert Response to IP and Port
    response = new String(anotherPacket.getData());
    splitResponse = response.split(":");
//    InetAddress Internal_IP = InetAddress.getByName(splitResponse[0].substring(1));

    int Internal_Port = Integer.parseInt(splitResponse[0]);

    // output converted Data for check
    System.out.println(" Internal PORT: " + Internal_Port);   
    }
     }
}

服务器 S 上的代码是:-

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class Servernew {
    public static void main(String args[]) throws Exception {

        DatagramSocket serverSocket2 = new DatagramSocket(6588);
        // Waiting for Connection of Client1 on Port 7070
        // ////////////////////////////////////////////////

        // open serverSocket on Port 7070
        DatagramSocket serverSocket1 = new DatagramSocket(7070);

        for(int i= 1; i<10;i++){

        System.out.println("Waiting for Client 1 on Port "
            + serverSocket1.getLocalPort());

        // receive Data
        DatagramPacket receivePacket = new DatagramPacket(new byte[1024], 1024);
        serverSocket1.receive(receivePacket);

        // Get  IP-Address and Port of Client1
        InetAddress IPAddress1 = receivePacket.getAddress();
        int port1 = receivePacket.getPort();
        String FirstmsgInfoOfClient1 = IPAddress1 + "-" + port1 + "-";

        System.out.println("Client1 External: " + FirstmsgInfoOfClient1);

        // Get Message from Client
        DatagramPacket anotherPacket = new DatagramPacket(new byte[1024], 1024);
        serverSocket1.receive(anotherPacket);

        // Decode the String
        String response = new String(anotherPacket.getData());
        String[] splitResponse = response.split(":");
//        InetAddress LocalIP1 = InetAddress.getByName(splitResponse[0].substring(1));
        int LocalPort1 = Integer.parseInt(splitResponse[0]);
//        int LocalPort1 = Integer.parseInt(splitResponse[1]);
//        String msgInfoOfClient1 = PortLocal+":PortLocal";
        String SecondmsgInfoOfClient1 = LocalPort1+":LocalPort1";

        System.out.println("Client1 Internal: " + SecondmsgInfoOfClient1);
//        System.out.println(response);



        // Waiting for Connection of Client2 on Port 6588
        // ////////////////////////////////////////////////

        // open serverSocket on Port 6588

//         DatagramSocket serverSocket2 = new DatagramSocket(6588);

        System.out.println("Waiting for Client 2 on Port "
            + serverSocket2.getLocalPort());

        // receive Data
        receivePacket = new DatagramPacket(new byte[1024], 1024);
        serverSocket2.receive(receivePacket);

        // GetIP-Address and Port of Client1
        InetAddress IPAddress2 = receivePacket.getAddress();
        int port2 = receivePacket.getPort();
        String FirstmsgInfoOfClient2 = IPAddress2 + "-" + port2 + "-";

        System.out.println("Client2 External:" + FirstmsgInfoOfClient2);

         // Get Message from Client
        anotherPacket = new DatagramPacket(new byte[1024], 1024);
        serverSocket2.receive(anotherPacket);

        // Decode the String

        response = new String(anotherPacket.getData());
        splitResponse = response.split(":");
//        InetAddress LocalIP1 = InetAddress.getByName(splitResponse[0].substring(1));
        int LocalPort2 = Integer.parseInt(splitResponse[0]);
//        int LocalPort1 = Integer.parseInt(splitResponse[1]);
//        
        String SecondmsgInfoOfClient2 = LocalPort2+":LocalPort2";

        System.out.println("Client2 Internal: " + SecondmsgInfoOfClient2);

        // Send the Information to the other Client
        /////////////////////////////////////////////////

        // Send Information of Client2 to Client1
        serverSocket1.send(new DatagramPacket(FirstmsgInfoOfClient2.getBytes(),
            FirstmsgInfoOfClient2.getBytes().length, IPAddress1, port1));

        serverSocket1.send(new DatagramPacket(SecondmsgInfoOfClient2.getBytes(), 
                SecondmsgInfoOfClient2.getBytes().length, IPAddress1, port1));


        // Send Infos of Client1 to Client2
        serverSocket2.send(new DatagramPacket(FirstmsgInfoOfClient1.getBytes(),
            FirstmsgInfoOfClient1.getBytes().length, IPAddress2, port2));

        serverSocket2.send(new DatagramPacket(SecondmsgInfoOfClient1.getBytes(), 
                SecondmsgInfoOfClient1.getBytes().length, IPAddress2, port2));

            System.out.println("-----------------\n");
            System.out.println("---------------------");
        }

        //close Sockets
        serverSocket1.close();
        serverSocket2.close();
}
}

输出是他们很好地交换了内部和外部端口以及公共 IP。

所以问题是如何使用这些信息来打开 A 和 B 之间的 TCP 连接?如何使用 Java 实现 TCP 打孔?

PS:最有必要成为一个 TCP 连接,我使用 Java 来做到这一点。

4

1 回答 1

0

在 S 上打开两个ServerSocket,接受来自 A 和 B 的连接(分别为端口 62000 和 31000)。当accept在每种情况下返回一个实例时,然后使用and将每个实例的andSocket交叉到另一个实例中。您需要为每个线程设置一个线程。InputStreamOutputStreamPipedOutputStreamPipedInputStream

于 2015-07-21T10:57:57.547 回答