我有一个设置,其中2 pc(比方说A和B)在每个公共IP的NAT后面。所以他们每个人都有自己不同的私有IP。我正在使用中间的服务器,它将交换IP地址和端口号。的A和B.他们也交换他们的内部港口号..!如何在不同网络的NAT后面的两个客户端之间建立TCP连接?
所以基本上这是设置。
客户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 Punch洞?
P.S:这是最有必要成为一个TCP连接,我用Java来做到这一点。
看到这个答案http://stackoverflow.com/a/31955934/395131 – Tahlil