Java实现TCP穿透NAT技术该怎么实现
在做一个远程文件管理系统的时候,需要用到TCP穿透NAT技术,在网上找了很多的资料都是理论的讲解,根据理论自己琢磨了好几天,程序还是一直都有问题。请教一下高手,该怎么实现TCP穿透NAT呀!!!
我把我自己写的代码贴出来,大家看看该怎么改嘛。
在线等呃。。。
服务器的代码:
public class TcpServer{
public static int count = 0;
public static ArrayList<InetAddress> list_address_1 = new ArrayList<InetAddress>();
public static ArrayList<InetAddress> list_address_2 = new ArrayList<InetAddress>();
public static ArrayList<String> list_port_1 = new ArrayList<String>();
public static ArrayList<String> list_port_2 = new ArrayList<String>();
public static ArrayList<Socket> list_socket = new ArrayList<Socket>();
public TcpServer() {
try {
ServerSocket s_socket = new ServerSocket(6789);
System.out.println("服务器开始监听6789端口");
while(true) {
Socket socket = s_socket.accept();
System.out.println("客户端的IP:" + socket.getInetAddress() + "\t客户端的端口号是:" + socket.getPort());
System.out.println("IP:" + socket.getLocalAddress() + "\tPort:" + socket.getLocalPort());
try {
System.out.println("Socket is " + socket);
Thread input = new InputThread(socket.getInputStream(), socket);
input.start();
System.out.println("写入线程开启...");
Thread output = new OutputThread(socket.getOutputStream());
output.start();
System.out.println("输出线程开启...");
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("Message is " + e.getMessage());
e.printStackTrace();
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("Message " + e.getMessage());
e.printStackTrace();
}
}
public static void connect() {
Socket socket_1 = list_socket.get(0);
Socket socket_2 = list_socket.get(1);
OutputStream out_1 = null;
OutputStream out_2 = null;
try {
out_1 = socket_1.getOutputStream();
out_2 = socket_2.getOutputStream();
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("Conect " + e.getMessage());
e.printStackTrace();
}
Writer writer_1 = new OutputStreamWriter(out_1);
Writer writer_2 = new OutputStreamWriter(out_2);
String str_1_1 = new String(list_address_1.get(1).toString().getBytes(), 1, list_address_1.get(1).toString().getBytes().length - 1);
String str_1_2 = new String(list_address_2.get(1).toString().getBytes(), 1, list_address_2.get(1).toString().getBytes().length - 1);
String str_2_1 = new String(list_address_1.get(0).toString().getBytes(), 1, list_address_1.get(0).toString().getBytes().length - 1);
String str_2_2 = new String(list_address_2.get(0).toString().getBytes(), 1, list_address_2.get(0).toString().getBytes().length - 1);
String msg_1 = "<connection>:" + str_1_1 + ":" + list_port_1.get(1) + ":" + str_1_2 + ":" + list_port_2.get(1);
String msg_2 = "<connection>:" + str_2_1 + ":" + list_port_1.get(0) + ":" + str_2_2 + ":" + list_port_2.get(0);
try {
writer_1.write(msg_1);
writer_1.flush();
writer_2.write(msg_2);
writer_2.flush();
System.out.println("开始中转连接");
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("456_" + e.getMessage());
e.printStackTrace();
}
}
public static void main(String[] args) {
new TcpServer();
}
}
class InputThread extends Thread {
InputStream in = null;
Socket socket = null;
public InputThread(InputStream input, Socket socket) {
this.in = input;
this.socket = socket;
}
public void run() {
try {
while(true) {
byte[] b = new byte[80];
int i = in.read(b);
if (i == -1) {
break;
}
System.out.write(i);
String str = new String(b, 0, b.length);
String string = str.trim();
System.out.println("Message is " + string);
if (string.indexOf("<connection>") != -1) {
String[] s = string.split(":");
TcpServer.list_address_1.add(InetAddress.getByName(s[1]));
TcpServer.list_port_1.add(s[2]);
TcpServer.list_address_2.add(socket.getInetAddress());
TcpServer.list_port_2.add(Integer.toString(socket.getPort()));
TcpServer.list_socket.add(socket);
TcpServer.count ++;
System.out.println("连接成功,已经成功连接" + TcpServer.count + "个。");
if (TcpServer.count == 2) {
TcpServer.connect();
}
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("Input Message is " + e.getMessage());
e.printStackTrace();
}
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("Close " + e.getMessage());
e.printStackTrace();
}
}
}
class OutputThread extends Thread {
private Writer writer = null;
public OutputThread(OutputStream out) {
this.writer = new OutputStreamWriter(out);
}
public void run() {
String line;
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
try {
while(true) {
line = in.readLine();
if (line.equals(".")) {
break;
}
writer.write(line + "\r\n");
writer.flush();
}
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("1_" + e.getMessage());
e.printStackTrace();
}
try {
writer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("2_" + e.getMessage());
e.printStackTrace();
}
}
}
[解决办法]
我记得NAT穿透技术都是通过UDP才能实现
TCP有三次握手机制,必须要有一方做为发起方,一方做为接收方,但是接收方是不可见的,SYN必然失败,无解
网上说通过TCP实现NAT穿透都是骗人的,其实质是服务建立两个TCP连接,然后转发数据