利用socket转发消息实现内网穿透

  1. 必须有一台中间机器,必须有公网ip。

1.socket 中转类

package Tools;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class TransPortData extends Thread {
          
   

    Socket getDataSocket;
    Socket putDataSocket;

    String type;

    public TransPortData(Socket getDataSocket, Socket putDataSocket, String type) {
          
   
        this.getDataSocket = getDataSocket;
        this.putDataSocket = putDataSocket;
        this.type = type;
    }

    @Override
    public void run() {
          
   
        try {
          
   
            System.out.println("被启动了");
            InputStream in = getDataSocket.getInputStream();
            OutputStream out = putDataSocket.getOutputStream();
            Long lastTime = System.currentTimeMillis();
            while (true) {
          
   
                //读入数据
                byte[] data = new byte[1024];
                int readlen = in.read(data);
                if (System.currentTimeMillis() - lastTime > 60000L) {
          
   
                    break;
                }

                if (getDataSocket.isClosed() || putDataSocket.isClosed()) {
          
   
                    break;
                }
                //如果没有数据,则暂停
                if (readlen <= 0) {
          
   
                    Thread.sleep(300);
                    continue;
                }
                lastTime = System.currentTimeMillis();
                out.write(data, 0, readlen);
                out.flush();
            }
        } catch (Exception e) {
          
   
            System.out.println("type:" + type);
            e.printStackTrace();
        } finally {
          
   
            //关闭socket
            try {
          
   
                if (putDataSocket != null) {
          
   
                    putDataSocket.close();
                }
            } catch (Exception exx) {
          
   
            }

            try {
          
   
                if (getDataSocket != null) {
          
   
                    getDataSocket.close();
                }
            } catch (Exception exx) {
          
   

            }
        }
    }

}

2.常量类

package Tools;

public interface Constants {
          
   
    // 服务端地址,支持IP或域名,这个根据服务端放的网络位置进行设置
    String serviceIp = "127.0.0.1";
    // 客户端服务的端口
    int servicePort = 10010;

    //中转端口
    int transferPort = 8080;
    //出口地址
    String destIp = "192.168.101.29";
    //出口端口
    int destPort = 3389;

}

3.测试类

package simple;

import Tools.Constants;
import Tools.TransPortData;

import java.io.IOException;
import java.lang.reflect.Array;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Arrays;
import java.util.List;

public class ServerApp {
          
   
    public static void main(String[] args) throws IOException {
          
   
        ServerSocket socket=new ServerSocket(Constants.servicePort);
        Socket clientSocket = null;
        Socket remoteServerSocket = null;
        System.out.println("服务器启动等待连接");
        while(true){
          
   
            try {
          
   
                //获取客户端连接
                clientSocket = socket.accept();


                System.out.println("accept one client");
                //建立远程连接
                remoteServerSocket = new Socket(Constants.destIp, Constants.destPort);
                System.out.println("create remoteip and port success");
                //启动数据转换接口
                (new TransPortData(clientSocket ,remoteServerSocket ,"1")).start();
                (new TransPortData(remoteServerSocket ,clientSocket,"2")).start();


            } catch (Exception ex) {
          
   
                ex.printStackTrace();
            }
            //建立连接远程
        }

    }

 

}
经验分享 程序员 微信小程序 职场和发展