网站首页 > 知识剖析 正文
先上样例
创建Maven项目
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.wpf</groupId>
<artifactId>WindowsPortForward</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<name>WindowsPortForward</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.25</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5</version>
<configuration>
<source>8</source>
<target>8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>org.wpf.App</mainClass>
</manifest>
<manifestEntries>
<Class-Path>.</Class-Path>
</manifestEntries>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>src/assembly/assembly.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
assembly.xml
可以把依赖代码打包到一起;存放位置:src/assembly/assembly.xml
<assembly>
<id>jar-with-dependencies</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<!-- 默认的配置 -->
<dependencySet>
<outputDirectory>/</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<unpack>true</unpack>
<scope>runtime</scope>
</dependencySet>
<!-- 增加scope类型为system的配置 -->
<dependencySet>
<outputDirectory>/</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<unpack>true</unpack>
<scope>system</scope>
</dependencySet>
</dependencySets>
</assembly>
Javafx 启动类
package org.wpf;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.image.Image;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Line;
import javafx.stage.Stage;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
/**
* lucy
*
*/
public class App extends Application {
private final ObservableList<WPF> data = FXCollections.observableArrayList();
private static final Set<Integer> ports= new HashSet<>();
public static void main( String[] args ) {
launch(args);
}
public void start(Stage primaryStage) throws Exception {
AnchorPane root = new AnchorPane();
Label agentPortLabel = new Label("代理端口:");
agentPortLabel.setStyle("-fx-font-family: '宋体'; -fx-font-weight: bold;");
AnchorPane.setTopAnchor(agentPortLabel,10.0);
AnchorPane.setLeftAnchor(agentPortLabel,10.0);
TextField agentPortTextField = new TextField();
agentPortTextField.setPrefWidth(65.0);
AnchorPane.setTopAnchor(agentPortTextField,7.0);
AnchorPane.setLeftAnchor(agentPortTextField,70.0);
agentPortTextField.setPromptText("1~65535");
agentPortTextField.setAlignment(Pos.BASELINE_LEFT);
Label targetIPLabel = new Label("目标IP:");
targetIPLabel.setStyle("-fx-font-family: '宋体'; -fx-font-weight: bold;");
AnchorPane.setTopAnchor(targetIPLabel,10.0);
AnchorPane.setLeftAnchor(targetIPLabel,140.0);
TextField agentIPTextField = new TextField();
agentIPTextField.setPrefWidth(140.0);
AnchorPane.setTopAnchor(agentIPTextField,7.0);
AnchorPane.setLeftAnchor(agentIPTextField,185.0);
agentIPTextField.setPromptText("ipv4");
agentIPTextField.setAlignment(Pos.BASELINE_LEFT);
Label targetPortLabel = new Label("目标端口:");
targetPortLabel.setStyle("-fx-font-family: '宋体'; -fx-font-weight: bold;");
AnchorPane.setTopAnchor(targetPortLabel,10.0);
AnchorPane.setLeftAnchor(targetPortLabel,330.0);
TextField targetPortTextField = new TextField();
targetPortTextField.setPrefWidth(65.0);
AnchorPane.setTopAnchor(targetPortTextField,7.0);
AnchorPane.setLeftAnchor(targetPortTextField,390.0);
targetPortTextField.setPromptText("1~65535");
targetPortTextField.setAlignment(Pos.BASELINE_LEFT);
Button button = new Button("端口转发");
button.setStyle("-fx-background-color: #3378d2;-fx-text-fill: white; -fx-font-size: 12px;");
AnchorPane.setTopAnchor(button,6.0);
AnchorPane.setLeftAnchor(button,480.0);
button.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
String agentPort = agentPortTextField.getText();
String targetPort = targetPortTextField.getText();
String agentIP = agentIPTextField.getText();
if(StrUtil.isEmpty(agentPort)||!Validator.isNumber(agentPort)||Convert.toInt(agentPort)>65535||Convert.toInt(agentPort)<=0){
Alert alert = new Alert(Alert.AlertType.ERROR, "请输入正确的代理端口,端口范围[1~65535]");
alert.showAndWait();
return;
}
if(StrUtil.isEmpty(targetPort)||!Validator.isNumber(targetPort)||Convert.toInt(targetPort)>65535||Convert.toInt(targetPort)<=0){
Alert alert = new Alert(Alert.AlertType.ERROR, "请输入正确的目标端口,端口范围[1~65535]");
alert.showAndWait();
return;
}
if(!Validator.isIpv4(agentIP)){
Alert alert = new Alert(Alert.AlertType.ERROR, "请输入正确的IPV4地址");
alert.showAndWait();
return;
}
if(ports.contains(Convert.toInt(agentPort))){
Alert alert = new Alert(Alert.AlertType.ERROR, "当前端口已经被代理,请更换其他端口");
alert.showAndWait();
return;
}
ports.add(Convert.toInt(agentPort));
start(Convert.toInt(agentPort), agentIP,Convert.toInt(targetPort));
WPF wpf = new WPF(Convert.toInt(agentPort), Convert.toInt(targetPort), agentIP);
data.add(wpf);
}
});
Line line = new Line(0,40,9999,0);
line.setStroke(Color.GRAY);
TableView<WPF> table = new TableView<WPF>();
table.setItems(data);
TableColumn<WPF, Integer> agentPortCol = new TableColumn<WPF, Integer>("代理端口");
agentPortCol.setCellValueFactory(new PropertyValueFactory<>("sourcePort"));
agentPortCol.setStyle("-fx-font-size: 14px;");
TableColumn<WPF, String> targetIPCol = new TableColumn<WPF, String>("目标IP");
targetIPCol.setPrefWidth(240);
targetIPCol.setCellValueFactory(new PropertyValueFactory<>("targetIP"));
targetIPCol.setStyle("-fx-font-size: 14px;");
TableColumn<WPF, String> targetPortCol = new TableColumn<WPF, String>("目标端口");
targetPortCol.setCellValueFactory(new PropertyValueFactory<>("targetPort"));
targetPortCol.setStyle("-fx-font-size: 14px;");
TableColumn<WPF, Void> statusCol = new TableColumn<WPF, Void>("启用/停用");
statusCol.setPrefWidth(110);
statusCol.setCellFactory(param -> new TableCellWithToggleButton(row -> {
}));
TableColumn<WPF, Void> operationCol = new TableColumn<WPF, Void>("操作");
operationCol.setPrefWidth(110);
operationCol.setCellFactory(param -> new TableCellWithButton( row -> {
int sourcePort = row.getSourcePort();
String targetIP = row.getTargetIP();
int targetPort = row.getTargetPort();
stop(sourcePort,targetIP,targetPort);
ports.remove(sourcePort);
data.remove(row);
}));
table.getColumns().addAll(agentPortCol,targetIPCol,targetPortCol,statusCol,operationCol);
AnchorPane.setTopAnchor(table,50.0);
AnchorPane.setLeftAnchor(table,5.0);
AnchorPane.setRightAnchor(table,5.0);
root.getChildren().addAll(agentPortLabel,agentPortTextField,targetIPLabel,agentIPTextField,targetPortLabel,targetPortTextField,button,line,table);
Scene scene = new Scene(root,600,300);
primaryStage.getIcons().add(new Image("/logo.png"));//设置图标
primaryStage.setScene(scene);
primaryStage.show();
}
public static void start(int sourcePort,String targetIP,int targetPort){
String[] command = {"cmd.exe", "/c", "netsh", "interface", "portproxy", "add", "v4tov4", "listenport="+sourcePort, "listenaddress=127.0.0.1", "connectport="+targetPort, "connectaddress="+targetIP};
try{
// 使用管理员权限执行命令
ProcessBuilder builder = new ProcessBuilder(command);
builder.redirectErrorStream(true);
Process process = builder.start();
// 获取命令执行结果
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream(), "GBK"));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
// 等待命令执行完成
int exitCode = process.waitFor();
System.out.println("Command executed with exit code: " + exitCode);
} catch (IOException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
public void init(){
String[] command = {"cmd.exe", "/c", "netsh", "interface", "portproxy", "show", "all"};
try{
// 使用管理员权限执行命令
ProcessBuilder builder = new ProcessBuilder(command);
builder.redirectErrorStream(true);
Process process = builder.start();
// 获取命令执行结果
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream(), "GBK"));
String line;
while ((line = reader.readLine()) != null) {
if(line.startsWith("127.0.0.1")){
List<String> slist = removeEmptyElements(StrUtil.split(line, " "));
WPF wpf = new WPF(Convert.toInt(slist.get(1)), Convert.toInt(slist.get(3)), slist.get(2));
data.add(wpf);
ports.add(Convert.toInt(slist.get(1)));
}
}
// 等待命令执行完成
int exitCode = process.waitFor();
System.out.println("Command executed with exit code: " + exitCode);
} catch (IOException | InterruptedException e) {
throw new RuntimeException(e);
}
}
public static List<String> removeEmptyElements(List<String> slist){
List<String> tlist = new ArrayList<>();
for (String str : slist) {
if (!str.isEmpty()) {
tlist.add(str.trim());
}
}
return tlist;
}
public static void stop(int sourcePort,String targetIP,int targetPort){
String[] command = {"cmd.exe", "/c", "netsh", "interface", "portproxy", "delete", "v4tov4", "listenport="+sourcePort, "listenaddress=127.0.0.1"};
try{
// 使用管理员权限执行命令
ProcessBuilder builder = new ProcessBuilder(command);
builder.redirectErrorStream(true);
Process process = builder.start();
// 获取命令执行结果
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream(), "GBK"));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
// 等待命令执行完成
int exitCode = process.waitFor();
System.out.println("Command executed with exit code: " + exitCode);
} catch (IOException | InterruptedException e) {
throw new RuntimeException(e);
}
}
public static class TableCellWithButton extends TableCell<WPF, Void> {
private final Button button;
public TableCellWithButton(ButtonClickedAction action) {
this.button = new Button();
button.setStyle("-fx-pref-width:20px; -fx-pref-height: 8px; -fx-background-color: red; -fx-shape: 'M909.5 242.1H147.6c-13.3 0-24.1-10.9-24.1-24.1v-8.4c0-13.3 10.9-24.1 24.1-24.1h761.9c13.3 0 24.1 10.9 24.1 24.1v8.4c0 13.2-10.8 24.1-24.1 24.1zM701.8 870H351.9c-71 0-128.8-57.8-128.8-128.8V213.7h51.5v527.5c0 42.6 34.7 77.3 77.3 77.3h349.9c42.6 0 77.3-34.7 77.3-77.3V213.7h51.5v527.5c0 71-57.8 128.8-128.8 128.8zM647.7 186h-51.5c0-28.4-29.9-51.6-66.7-51.6-36.7 0-66.6 23.1-66.6 51.6h-51.5c0-56.9 53-103.1 118.1-103.1S647.7 129.1 647.7 186zM384.2 708.5h-2.9c-13.4 0-24.3-10.9-24.3-24.3V373.8c0-13.4 10.9-24.3 24.3-24.3h2.9c13.4 0 24.3 10.9 24.3 24.3v310.4c0 13.3-10.9 24.3-24.3 24.3zM531 708.5h-2.9c-13.4 0-24.3-10.9-24.3-24.3V373.8c0-13.4 10.9-24.3 24.3-24.3h2.9c13.4 0 24.3 10.9 24.3 24.3v310.4c0 13.3-10.9 24.3-24.3 24.3zM677.8 708.5h-2.9c-13.4 0-24.3-10.9-24.3-24.3V373.8c0-13.4 10.9-24.3 24.3-24.3h2.9c13.4 0 24.3 10.9 24.3 24.3v310.4c0 13.3-11 24.3-24.3 24.3z'");
this.button.setOnAction(event -> {
action.handle(getTableView().getItems().get(getIndex()));
});
}
@Override
protected void updateItem(Void item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setGraphic(null);
} else {
setGraphic(button);
}
setAlignment(Pos.CENTER);
}
}
public static class TableCellWithToggleButton extends TableCell<WPF, Void> {
private final ToggleButton button;
public TableCellWithToggleButton(ButtonClickedAction action) {
this.button = new ToggleButton();
button.setStyle("-fx-pref-width:45px; -fx-pref-height: 10px; -fx-background-color:#33d260; -fx-shape: 'M366 294.504c-132 0-240 107.104-240 238s108 238 240 238h304c132 0 240-107.104 240-238s-108-238-240-238h-304z m308 442.16c-111.28 0-201.504-91.408-201.504-204.168s90.224-204.16 201.504-204.16 201.504 91.408 201.504 204.168-90.224 204.16-201.504 204.16z'");
// 设置按钮初始状态
button.setSelected(true); // 初始状态为未选中
this.button.setOnAction(event -> {
WPF wpf = getTableView().getItems().get(getIndex());
if (button.isSelected()) {
//按钮状态:开
button.setStyle("-fx-pref-width:45px; -fx-pref-height: 10px; -fx-background-color:#33d260; -fx-shape: 'M366 294.504c-132 0-240 107.104-240 238s108 238 240 238h304c132 0 240-107.104 240-238s-108-238-240-238h-304z m308 442.16c-111.28 0-201.504-91.408-201.504-204.168s90.224-204.16 201.504-204.16 201.504 91.408 201.504 204.168-90.224 204.16-201.504 204.16z'");
App.start(wpf.getSourcePort(),wpf.getTargetIP(),wpf.getTargetPort());
ports.add(wpf.getSourcePort());
} else {
//按钮状态:关
button.setStyle(" -fx-pref-width:45px; -fx-pref-height: 10px; -fx-shape: 'M2 512c0-141 114-255 255-255h510c141 0 255 114 255 255S908 767 767 767H257C116 767 2 653 2 512z m255 208.8c115.5 0 208.8-93.2 208.8-208.8S372.5 303.2 257 303.2c-115.5 0-208.8 93.2-208.8 208.8S141.5 720.8 257 720.8z'");
App.stop(wpf.getSourcePort(),wpf.getTargetIP(),wpf.getTargetPort());
}
action.handle(wpf);
});
}
@Override
protected void updateItem(Void item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setGraphic(null);
} else {
setGraphic(button);
}
setAlignment(Pos.CENTER);
}
}
@FunctionalInterface
public interface ButtonClickedAction {
void handle(WPF person);
}
public static class WPF{
private int sourcePort;
private int targetPort;
private String targetIP;
public WPF(int sourcePort, int targetPort, String targetIP) {
this.sourcePort = sourcePort;
this.targetPort = targetPort;
this.targetIP = targetIP;
}
public int getSourcePort() {
return sourcePort;
}
public void setSourcePort(int sourcePort) {
this.sourcePort = sourcePort;
}
public int getTargetPort() {
return targetPort;
}
public void setTargetPort(int targetPort) {
this.targetPort = targetPort;
}
public String getTargetIP() {
return targetIP;
}
public void setTargetIP(String targetIP) {
this.targetIP = targetIP;
}
}
}
资源文件
resource目录下存放logo.png,网上随便找到。别投诉我侵权哦。
打包启动
java -jar WindowsPortForward-1.0.0-jar-with-dependencies.jar
注意
使用管理员身份启动cmd,并运行启动命令。
转发一个端口测试下
- 上一篇: “万能”箭头函数?你可能要失望了
- 下一篇: WebAPI详细解说【思维导图】(webapi视频教程)
猜你喜欢
- 2024-11-15 HTML中为元素绑定Class属性与Style样式
- 2024-11-15 不容忽视的 8 个 DOM API(dom based)
- 2024-11-15 WebAPI详细解说【思维导图】(webapi视频教程)
- 2024-11-15 “万能”箭头函数?你可能要失望了
- 2024-11-15 React-鼠标事件处理(react doubleclick)
- 2024-11-15 深入了解 LocalStorage:JavaScript 中的数据存储利器
- 2024-11-15 JavaScript-浏览器兼容的脚本化class操作
- 2024-11-15 Bootstrap在React中的实现,易于使用的React组件——Reactstrap
- 2024-11-15 Vue3.0新特性探索(vue3.0新特性的typescript)
- 2024-11-15 超简单的网站暗黑模式,它真的超简单
- 最近发表
- 标签列表
-
- xml (46)
- css animation (57)
- array_slice (60)
- htmlspecialchars (54)
- position: absolute (54)
- datediff函数 (47)
- array_pop (49)
- jsmap (52)
- toggleclass (43)
- console.time (63)
- .sql (41)
- ahref (40)
- js json.parse (59)
- html复选框 (60)
- css 透明 (44)
- css 颜色 (47)
- php replace (41)
- css nth-child (48)
- min-height (40)
- xml schema (44)
- css 最后一个元素 (46)
- location.origin (44)
- table border (49)
- html tr (40)
- video controls (49)