java实现端口转发_Java实现端口映射/转发

这是一个使用Java实现的简单端口转发程序,通过创建ServerSocket监听本地端口,当有新的连接请求时,程序会与指定的目标主机建立连接,并进行数据的双向转发,实现端口映射功能。同时,程序还包含了自动清除失效和超时连接的机制。
摘要由CSDN通过智能技术生成

1 importjava.io.IOException;2 importjava.io.InputStream;3 importjava.io.OutputStream;4 importjava.net.ServerSocket;5 importjava.net.Socket;6 importjava.text.SimpleDateFormat;7 import java.util.*;8

9 public class SimpleForward implementsRunnable {10 //服务器

11 privateServerSocket server;12 //监听本地端口

13 private int localPort = 1080;14 //目标主机地址

15 private String remoteHostAddr = "0.0.0.0";16 //目标主机端口

17 private int remoteHostPort = 8388;18 //设置超时时间 30s

19 private static int TIMEOUT = 30;20 //客户端列表 用于删除失效连接和超时连接

21 private static HashMap clientList = new HashMap<>();22

23 public static void main(String[] args) throwsIOException {24 //new SimpleForward();

25 new SimpleForward(1234, "127.0.0.1", 1080);26 }27

28 public SimpleForward() throwsIOException {29 run();30 }31

32 public SimpleForward(int localPort, String remoteHostAddr, int remoteHostPort) throwsIOException {33 this.localPort =localPort;34 this.remoteHostAddr =remoteHostAddr;35 this.remoteHostPort =remoteHostPort;36 run();37 }38

39 @Override40 public voidrun() {41 try{42 this.server = new ServerSocket(this.localPort);43 System.out.println("服务器开启成功");44 System.out.println("监听端口 : " + this.localPort);45 } catch(IOException e) {46 System.out.println("服务器开启失败");47 System.out.println(e.getMessage());48 System.out.println("退出运行");49 return;50 }51 //自动清除失效连接和超时连接

52 new Thread(newTerminal()).start();53 new Thread(newAutoDestroy()).start();54 while (true) {55 Socket socket = null;56 Socket remoteHost = null;57 try{58 socket =server.accept();59 //接收到请求就把socket扔进map,value为刷新时间

60 clientList.put(socket, newDate());61 String address =socket.getRemoteSocketAddress().toString();62 System.out.println("新连接 : " +address);63 //建立与目标主机的连接

64 remoteHost = new Socket(this.remoteHostAddr, this.remoteHostPort);65 System.out.println("连接地址 : " + this.remoteHostAddr + ":" + this.remoteHostPort);66 //端口转发

67 new Thread(newSwitch(socket, remoteHost, remoteHost.getInputStream(), socket.getOutputStream())).start();68 new Thread(newSwitch(socket, remoteHost, socket.getInputStream(), remoteHost.getOutputStream())).start();69 } catch(IOException e) {70 System.out.println("连接异常");71 System.out.println(e.getMessage());72 close(socket);73 close(remoteHost);74 }75 }76 }77

78 private voidclose(Socket socket) {79 try{80 if (socket != null) {81 socket.close();82 }83 } catch(IOException e) {84 e.printStackTrace();85 }86 }87

88 //用于端口转发

89 private class Switch implementsRunnable {90 privateSocket host;91 privateSocket remoteHost;92 privateInputStream in;93 privateOutputStream out;94

95 Switch(Socket host, Socket remoteHost, InputStream in, OutputStream out) {96 this.host =host;97 this.remoteHost =remoteHost;98 this.in =in;99 this.out =out;100 }101

102 @Override103 public voidrun() {104 int length = 0;105 byte[] buffer = new byte[1024];106 try{107 while (!host.isClosed() && (length = in.read(buffer)) > -1) {108 clientList.put(host, newDate());109 out.write(buffer, 0, length);110 }111 } catch(IOException e) {112 System.out.println("连接关闭");113 } finally{114 close(host);115 close(remoteHost);116 }117 }118 }119

120 //用于清除失效连接和超时连接

121 private class AutoDestroy implementsRunnable {122

123 @Override124 public voidrun() {125 Timer timer = newTimer();126 timer.schedule(newTimerTask() {127 @Override128 public voidrun() {129 List list = new LinkedList<>();130 System.out.println("开始扫描失效与超时连接");131 Date start = newDate();132 for(Socket socket : clientList.keySet()) {133 Date lastTime =clientList.get(socket);134 long time = new Date().getTime() -lastTime.getTime();135 if (socket.isClosed() || time / 1000 >=TIMEOUT) {136 list.add(socket);137 }138 }139 System.out.println("找到" + list.size() + "个,用时 : " + (new Date().getTime() - start.getTime()) + "毫秒");140 System.out.println("开始清除失效与超时连接");141 for(Socket socket : list) {142 try{143 clientList.remove(socket);144 socket.close();145 } catch(IOException e) {146 e.printStackTrace();147 }148 }149 System.out.println("当前连接数 : " +clientList.size());150 }151 }, 30 * 1000, 30 * 1000);152 }153 }154

155 private class Terminal implementsRunnable {156 private ReaderUtil reader = newReaderUtil();157 private String format = "yyyy-MM-dd HH:mm:ss";158 private SimpleDateFormat dateFormat = newSimpleDateFormat(format);159

160 @Override161 public voidrun() {162 while (!server.isClosed()) {163 System.out.print("请输入命令 : ");164 String cmd =reader.readKB();165 handler(cmd);166 }167 }168

169 private voidhandler(String cmd) {170 switch(cmd) {171 case "status":172 System.out.println("当前时间 : " + dateFormat.format(newDate()));173 System.out.println("总连接数 : " +clientList.size());174 for(Socket socket : clientList.keySet()) {175 long time = new Date().getTime() -clientList.get(socket).getTime();176 System.out.println(" " + time / 1000);177 }178 break;179 }180 }181 }182 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值