增加启动xtcp frpc功能

This commit is contained in:
Administrator
2023-01-01 16:20:40 +08:00
parent 1af088a29d
commit 62b22410a3
90 changed files with 11649 additions and 11459 deletions
@@ -47,7 +47,7 @@ public class IOThreadManager {
}
Thread lt = ThreadTool.makeVThreadIfSupport("数据包计时重发线程", () -> {
Thread lt = ThreadTool.makeVThreadIfSupport("数据包计时重发线程", () -> {
try {
while (AB.get()) {
@@ -57,7 +57,7 @@ public class IOThreadManager {
}
});
Thread ls = ThreadTool.makeVThreadIfSupport("本地发送线程", () -> {
Thread ls = ThreadTool.makeVThreadIfSupport("本地发送线程", () -> {
try {
while (AB.get()) {
@@ -77,7 +77,6 @@ public class IOThreadManager {
sbk.number = 0;
sbk.command = 3;
klc.submitDataBlockNoDelay(sbk);
e.printStackTrace();
}finally {
try {
tc.getDout().close();
@@ -86,7 +85,7 @@ public class IOThreadManager {
}
}
});
Thread lr = ThreadTool.makeVThreadIfSupport("本地接收线程", () -> {
Thread lr = ThreadTool.makeVThreadIfSupport("本地接收线程", () -> {
try {
while (AB.get()) {
KLALBBlock ks = tc.packBlock();
@@ -105,7 +104,6 @@ public class IOThreadManager {
sbk.number = 0;
sbk.command = 3;
klc.submitDataBlockNoDelay(sbk);
e.printStackTrace();
} finally {
try {
tc.getDin().close();
@@ -143,7 +141,7 @@ public class IOThreadManager {
}
klc.getRemotetcps().add(tc);
try {
Thread rs = ThreadTool.makeVThreadIfSupport("远程发送线程", () -> {
Thread rs = ThreadTool.makeVThreadIfSupport("远程发送线程", () -> {
try {
while (true) {
@@ -151,17 +149,15 @@ public class IOThreadManager {
}
} catch (InterruptedException e) {
} catch (IOException e) {
e.printStackTrace();
}
});
Thread rr = ThreadTool.makeVThreadIfSupport("远程接收线程", () -> {
Thread rr = ThreadTool.makeVThreadIfSupport("远程接收线程", () -> {
try {
while (true) {
klc.remoteReceive(tc);
}
} catch (Exception e) {
rs.interrupt();
e.printStackTrace();
}
});
rs.start();
@@ -10,12 +10,12 @@ import org.kne.cloud.network.mport.IPPort;
public class KLALBBlock implements Comparable<KLALBBlock>{
private static AtomicLong sng=new AtomicLong(1);
public long sn;//每个数据包的唯一编号
public int cuid;//用于识别数据包的stream ID号
public long number;//数据包的编号,用于排序
public byte[]data;//数据内容
public int command;//功能标记 0=PING 1=PONG 2=SYN 3=RST
public long pingtime;//PING计时器
public long sn;//每个数据包的唯一编号
public int cuid;//用于识别数据包的stream ID号
public long number;//数据包的编号,用于排序
public byte[]data;//数据内容
public int command;//功能标记 0=PING 1=PONG 2=SYN 3=RST
public long pingtime;//PING计时器
public int cacheused;
public String lservice;
+13 -11
View File
@@ -15,8 +15,8 @@ public class KLALBCM {
public static void main(String[] args) throws IOException {
if(args.length==0){
System.out.println("命令行参数输入服务器任意一条线路的地址:端口可以下载服务器线路列表");
System.out.println("命令行参数输入服务器名称即可启动负载均衡");
System.out.println("命令行参数输入服务器任意一条线路的地址:端口可以下载服务器线路列表");
System.out.println("命令行参数输入服务器名称即可启动负载均衡");
}else if(args.length==1) {
if(args[0].equals("-gui")) {
KLALBClientGUI.main(args);
@@ -27,33 +27,35 @@ public class KLALBCM {
File pdis=KLALBIPList.getSLdir(args[0]);
File f=new File(pdis,"iplist.json");
if(f.exists()) {
System.out.println("加载线路列表:"+f);
byte[] bytes;
System.out.println("加载线路列表:"+f);
try {
KLALBIPList.updateIPList(args[0]);
bytes = Files.readAllBytes(Paths.get(f.toURI()));
STJson stj=new STJson(new String(bytes));
STJson stj=new STJson(new String(Files.readAllBytes(Paths.get(f.toURI()))));
KLALBClient kc= new KLALBClient();
kc.getTls().addAll(stj.getTunnels());
kc.connectTunnel();
List<ServiceElement> lse=stj.getServices();
ProxyJson pj=new ProxyJson(new File(pdis,"services.json"), stj);
kc.getPet().addAll(pj.getPls());
kc.listenProxy();
/* List<ServiceElement> lse=stj.getServices();
for (Iterator<ServiceElement> iterator = lse.iterator(); iterator.hasNext();) {
ServiceElement serviceElement = (ServiceElement) iterator.next();
ProxyIPPortProperties pippp=new ProxyIPPortProperties(pdis, serviceElement.name, "127.0.0.1", serviceElement.ipport.getPort());
ProxyIPPortProperties pippp=new ProxyIPPortProperties(pdis, serviceElement.name, "0.0.0.0", serviceElement.ipport.getPort());
try {
kc.open(pippp.getBindPort(),serviceElement, pippp.getBindIP());
}catch(BindException e) {
System.out.println("打开端口失败:"+pippp.getBindIP()+" "+pippp.getBindPort());
System.out.println("打开端口失败:"+pippp.getBindIP()+" "+pippp.getBindPort());
e.printStackTrace();
}
}
}*/
}catch (IOException e) {
e.printStackTrace();
}
}else {
System.out.println("线路列表不存在");
System.out.println("线路列表不存在");
}
}
}else {
@@ -25,6 +25,8 @@ import java.util.UUID;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import javax.swing.text.html.HTMLDocument.HTMLReader.PreAction;
import org.kne.cloud.network.mport.IPPort;
import org.kne.cloud.network.mport.ServiceElement;
import org.kne.cloud.network.mport.ThreadTool;
@@ -37,19 +39,19 @@ public class KLALBClient {
private IOThreadManager iom=new IOThreadManager();
private List<Tunnel> tls=new ArrayList<>();
private List<TCPListener> tcpl=new ArrayList<>();
private List<ProxyElement> pet=new ArrayList<>();
public void open(int port, ServiceElement sel,String bindip) throws IOException {
TCPListener tl=new TCPListener(port,bindip);
private void open(ProxyElement pe) throws IOException {
TCPListener tl=new TCPListener(pe.getIpport().getPort(),pe.getIpport().getIp());
tl.setCon((s)->{
LocalTCPConnection tcc = null;
try {
tcc = new LocalTCPConnection(s);
tcc.setServiceElement(sel);
//System.out.println("TCP"+tcc.getCuid()+"已连接");
tcc.setServiceElement(pe.getSe());
//System.out.println("TCP"+tcc.getCuid()+"已连接");
iom.handleLocal(tcc,true);
//System.out.println("TCP"+tcc.getCuid()+"已关闭");
//System.out.println("TCP"+tcc.getCuid()+"已关闭");
} catch (IOException e) {
e.printStackTrace();
}finally {
@@ -60,12 +62,22 @@ public class KLALBClient {
});
tl.open();
tcpl.add(tl);
System.out.println(sel.name+"映射已启动 端口:"+port+" 绑定地址:"+bindip);
System.out.println(pe.getSe().name+"映射已启动 端口:"+pe.getIpport().getPort()+" 绑定地址:"+pe.getIpport().getIp());
}
public void listenProxy() {
for (int i = 0; i < pet.size(); i++) {
ProxyElement pe=pet.get(i);
try {
open(pe);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void connectTunnel() {
for (int i = 0; i < tls.size(); i++) {
Tunnel tll=tls.get(i);
ThreadTool.makeVThreadIfSupport("隧道监视线程", ()->{
ThreadTool.makeVThreadIfSupport("隧道监视线程", ()->{
int re=0;
RemoteTCPConnection tc=null;
while(iom.isOpen()) {
@@ -84,10 +96,10 @@ public class KLALBClient {
throw new EOFException();
}
re=0;
System.out.println(tll+":连接成功");
System.out.println(tll+":连接成功");
tll.setState(true);
iom.handleRemote(tc);
System.out.println(tll+":连接断开");
System.out.println(tll+":连接断开");
tll.setState(false);
} catch (UnknownHostException e) {
e.printStackTrace();
@@ -112,6 +124,9 @@ public class KLALBClient {
public List<Tunnel> getTls() {
return tls;
}
public List<ProxyElement> getPet() {
return pet;
}
public List<ServiceElement> services=new ArrayList<ServiceElement>();
public List<ServiceElement> getServices() {
@@ -123,6 +138,9 @@ public class KLALBClient {
TCPListener tl = (TCPListener) iterator.next();
tl.close();
}
tls.forEach((v)->{
v.destroyFrpc();
});
}
@@ -85,13 +85,13 @@ public class KLALBClientGUI extends XFrame {
@Override
public void componentShown(ComponentEvent e) {
// TODO 自动生成的方法存根
// TODO 自动生成的方法存根
}
@Override
public void componentResized(ComponentEvent e) {
// TODO 自动生成的方法存根
// TODO 自动生成的方法存根
}
@@ -102,7 +102,7 @@ public class KLALBClientGUI extends XFrame {
@Override
public void componentHidden(ComponentEvent e) {
// TODO 自动生成的方法存根
// TODO 自动生成的方法存根
}
});
@@ -116,21 +116,21 @@ public class KLALBClientGUI extends XFrame {
JButton btnNewButton = new JButton("\u6DFB\u52A0");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String s = JOptionPane.showInputDialog(KLALBClientGUI.this, "输入一条线路的地址");
String s = JOptionPane.showInputDialog(KLALBClientGUI.this, "输入一条线路的地址");
if (s != null) {
if (s.equals("")) {
JOptionPane.showMessageDialog(KLALBClientGUI.this, "输入不能为空", "错误", JOptionPane.WARNING_MESSAGE);
JOptionPane.showMessageDialog(KLALBClientGUI.this, "输入不能为空", "错误", JOptionPane.WARNING_MESSAGE);
} else {
ProcessingFrame psf = new ProcessingFrame("正在下载线路列表");
ProcessingFrame psf = new ProcessingFrame("正在下载线路列表");
psf.setIconImage(bi);
psf.getProgressBar().setIndeterminate(true);
psf.setVisible(true);
ThreadTool.makeVThreadIfSupport("线路列表获取", () -> {
ThreadTool.makeVThreadIfSupport("线路列表获取", () -> {
try {
KLALBIPList.createIPList(s);
reloadCB();
} catch (Exception e1) {
JOptionPane.showMessageDialog(KLALBClientGUI.this, e1.toString(), "错误",
JOptionPane.showMessageDialog(KLALBClientGUI.this, e1.toString(), "错误",
JOptionPane.ERROR_MESSAGE);
e1.printStackTrace();
} finally {
@@ -152,7 +152,7 @@ public class KLALBClientGUI extends XFrame {
t=null;
return;
}
t=ThreadTool.makeVThreadIfSupport("客户端主线程", () -> {
t=ThreadTool.makeVThreadIfSupport("客户端主线程", () -> {
btnNewButton_1.setEnabled(false);
comboBox.setEnabled(false);
String s = (String) comboBox.getSelectedItem();
@@ -162,12 +162,10 @@ public class KLALBClientGUI extends XFrame {
File pdis = KLALBIPList.getSLdir(s);
File f = new File(pdis, "iplist.json");
if (f.exists()) {
System.out.println("加载线路列表:" + f);
byte[] bytes;KLALBClient kc=null;
System.out.println("加载线路列表:" + f);;KLALBClient kc=null;
try {
KLALBIPList.updateIPList(s);
bytes = Files.readAllBytes(Paths.get(f.toURI()));
STJson stj = new STJson(new String(bytes));
STJson stj=new STJson(new String(Files.readAllBytes(Paths.get(f.toURI()))));
kc = new KLALBClient();
kc.getTls().addAll(stj.getTunnels());
List<Tunnel>lt=kc.getTls();
@@ -206,20 +204,13 @@ public class KLALBClientGUI extends XFrame {
ysp.repaint();
repaint();
kc.connectTunnel();
List<ServiceElement> lse = stj.getServices();
for (Iterator<ServiceElement> iterator = lse.iterator(); iterator.hasNext();) {
ServiceElement serviceElement = (ServiceElement) iterator.next();
ProxyIPPortProperties pippp = new ProxyIPPortProperties(pdis, serviceElement.name,
"0.0.0.0", serviceElement.ipport.getPort());
try {
kc.open(pippp.getBindPort(), serviceElement, pippp.getBindIP());
} catch (BindException e) {
System.out.println("打开端口失败:" + pippp.getBindIP() + " " + pippp.getBindPort());
e.printStackTrace();
}
}
ProxyJson pj=new ProxyJson(new File(pdis,"services.json"), stj);
kc.getPet().addAll(pj.getPls());
kc.listenProxy();
btnNewButton_1.setForeground(Color.RED);
btnNewButton_1.setText("停止");
btnNewButton_1.setText("停止");
btnNewButton_1.setEnabled(true);
while(true) {
@@ -234,7 +225,7 @@ public class KLALBClientGUI extends XFrame {
}
} catch (ConnectException e) {
JOptionPane.showMessageDialog(KLALBClientGUI.this, e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
JOptionPane.showMessageDialog(KLALBClientGUI.this, e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
@@ -246,17 +237,17 @@ public class KLALBClientGUI extends XFrame {
}
} else {
System.out.println("线路列表不存在");
System.out.println("线路列表不存在");
}
btnNewButton_1.setForeground(Color.GREEN);
btnNewButton_1.setText("启动");
btnNewButton_1.setText("启动");
btnNewButton_1.setEnabled(true);
comboBox.setEnabled(true);
});t.start();
}
});
panel_1.add(btnNewButton_1, BorderLayout.EAST);
setTitle("KNE云网络负载均衡客户端");
setTitle("KNE云网络负载均衡客户端");
setSize(600, 370);
setLocationRelativeTo(null);
@@ -267,7 +258,7 @@ public class KLALBClientGUI extends XFrame {
TrayIcon ti = new TrayIcon(bi);
ti.setImageAutoSize(true);
PopupMenu jpm = new PopupMenu();
MenuItem mi = new MenuItem("退出");
MenuItem mi = new MenuItem("退出");
mi.addActionListener(new ActionListener() {
@Override
@@ -305,4 +296,4 @@ public class KLALBClientGUI extends XFrame {
public static void main(String[] args) {
new KLALBClientGUI();
}
}
}
@@ -276,7 +276,7 @@ public class KLALBCore {
for (int i = 0; i < l.size(); i++) {
KLALBBlock block=l.get(i);
long timex = (System.nanoTime() - block.sendtime) / 1000000;
if (timex > 100*(1<<Math.min(8,block.resend))+1000*i) {
if (timex > 200*(1<<Math.min(8,block.resend))+1000*i) {
submitDataBlock(block);
block.sendtime = System.nanoTime();
block.resend++;
@@ -284,7 +284,7 @@ public class KLALBCore {
l.remove(i);
i--;
}
System.out.println("³¬Ê±ÖØ´«£º"+block);
System.out.println("超时重传:"+block);
}
}
}
@@ -41,7 +41,7 @@ public class KLALBIPList {
String json=KLALBIPList.searchTunnels(address);
STJson stj=new STJson(json);
File f=new File(getSLdir(stj.getName()),"iplist.json");
System.out.println("线路列表已保存到:"+f);
System.out.println("线路列表已保存到:"+f);
f.getParentFile().mkdirs();
f.createNewFile();
PrintStream ps=new PrintStream(f);
@@ -63,6 +63,6 @@ public class KLALBIPList {
e.printStackTrace();
}
}
throw new ConnectException("搜索地址失败");
throw new ConnectException("搜索地址失败");
}
}
+3 -3
View File
@@ -17,11 +17,11 @@ import org.kne.cloud.network.mport.ServiceElement;
public class KLALBSM {
public static void main(String[] args) throws IOException {
System.out.println("KNE云负载均衡调度软件服务端V0.1");
System.out.println("KNE云负载均衡调度软件服务端V0.1");
ServerPropties sp=new ServerPropties();
int remp=sp.getPort();
System.out.println("开放端口:"+remp);
System.out.println("开放端口:"+remp);
new KLALBServer(remp,new Supplier<String>() {
@Override
@@ -37,7 +37,7 @@ public class KLALBSM {
return sj;
}
});
System.out.println("提示:运行时输入reload可以重新加载配置文件,已经建立的TCP连接不受影响(暂不支持修改开放端口)");
System.out.println("提示:运行时输入reload可以重新加载配置文件,已经建立的TCP连接不受影响(暂不支持修改开放端口)");
Scanner scn2=new Scanner(System.in);
while(true) {
String command=scn2.next();
@@ -47,7 +47,6 @@ public class KLALBServer {
tcc.setTunnel(tll);
UUID uid=new UUID(din.readLong(),din.readLong());
System.out.println(uid);
IOThreadManager nx = null;
synchronized (tcpl) {
if(whm.containsKey(uid)) {
@@ -57,9 +56,14 @@ public class KLALBServer {
IOThreadManager n1=nx;
nx.getCore().setAcceptSYN((b)->{
try {
STJson stj=new STJson(gjso.get());
if(!stj.checkSafety(b.lipport)) {
System.out.println("未授权的请求:"+b.lipport);
return false;
}
Socket soc=new Socket(b.lipport.getIp(),b.lipport.getPort());
LocalTCPConnection ltc=new LocalTCPConnection(soc, b.cuid);
ThreadTool.makeVThreadIfSupport("局域网连接监视线程", ()->{
ThreadTool.makeVThreadIfSupport("局域网连接监视线程", ()->{
try {
n1.handleLocal(ltc, false);
}finally {
@@ -68,7 +72,7 @@ public class KLALBServer {
}).start();
return true;
} catch (IOException e) {
System.out.println("连接本地服务"+b.lipport+"失败,请检查你的本地服务");
System.out.println("连接本地服务"+b.lipport+"失败,请检查你的本地服务");
e.printStackTrace();
}
return false;
@@ -0,0 +1,46 @@
package org.kne.cloud.network.klalb;
import java.util.Objects;
import org.kne.cloud.network.mport.IPPort;
import org.kne.cloud.network.mport.ServiceElement;
public class ProxyElement {
private ServiceElement se;
private IPPort ipport;
public ServiceElement getSe() {
return se;
}
public IPPort getIpport() {
return ipport;
}
@Override
public int hashCode() {
return Objects.hash(ipport, se);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ProxyElement other = (ProxyElement) obj;
return Objects.equals(ipport, other.ipport) && Objects.equals(se, other.se);
}
public ProxyElement(ServiceElement se, IPPort ipport) {
super();
this.se = se;
this.ipport = ipport;
}
public ProxyElement() {
}
public void setSe(ServiceElement se) {
this.se = se;
}
public void setIpport(IPPort ipport) {
this.ipport = ipport;
}
}
@@ -0,0 +1,101 @@
package org.kne.cloud.network.klalb;
import java.io.*;
import java.util.*;
import org.kne.cloud.network.mport.IPPort;
import org.kne.cloud.network.mport.ServiceElement;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
public class ProxyJson {
private File f;
private List<ProxyElement> pls=new ArrayList<>();
public List<ProxyElement> getPls() {
return pls;
}
public ProxyJson(File f,STJson def) throws IOException {
super();
this.f = f;
if(!f.exists()||f.length()==0l) {
f.createNewFile();
JsonWriter jw=null;
try {
jw=new JsonWriter(new FileWriter(f));
jw.setIndent(" ");
jw.beginObject();
jw.name("services");
jw.beginArray();
for (Iterator<ServiceElement> iterator = def.getServices().iterator(); iterator.hasNext();) {
ServiceElement proxye = (ServiceElement) iterator.next();
jw.beginObject();
jw.name("name");
jw.value(proxye.name);
jw.name("protocol");
jw.value(proxye.protocol);
jw.name("localaddress");
jw.value(proxye.ipport.toString());
jw.name("bindaddress");
jw.value("0.0.0.0:"+proxye.ipport.getPort());
jw.endObject();
}
jw.endArray();
jw.endObject();
}finally{
if(jw!=null)
jw.close();
}
}
JsonReader jr=null;
try {
jr=new JsonReader(new FileReader(f));
jr.beginObject();
while(jr.hasNext()) {
String name=jr.nextName();
switch(name) {
case "services":
jr.beginArray();
while(jr.hasNext()) {
jr.beginObject();
ProxyElement pe=new ProxyElement();
ServiceElement se=new ServiceElement();
pe.setSe(se);
while(jr.hasNext()) {
String n3=jr.nextName();
switch(n3) {
case "name":
se.name=jr.nextString();
break;
case "protocol":
se.protocol=jr.nextString();
break;
case "localaddress":
se.ipport=new IPPort (jr.nextString());
break;
case "bindaddress":
pe.setIpport(new IPPort (jr.nextString()));
break;
default:
jr.skipValue();
break;
}
}
pls.add(pe);
jr.endObject();
}
jr.endArray();
break;
default:
jr.skipValue();
break;
}
}
jr.endObject();
}finally {
if(jr!=null)
jr.close();
}
}
}
@@ -61,6 +61,16 @@ public class STJson {
t.setName(sr.nextString());
} else if (n2.equals("remoteaddress")) {
t.setIpport(new IPPort( sr.nextString()));
} else if (n2.equals("frpc")) {
StringBuilder sbd=new StringBuilder();
sr.beginArray();
while(sr.hasNext()) {
sbd.append(sr.nextString());
sbd.append('\r');
sbd.append('\n');
}
sr.endArray();
t.setFrpc(sbd.toString());
} else{
sr.skipValue();
}
@@ -81,4 +91,14 @@ public class STJson {
return name;
}
public boolean checkSafety(IPPort lipport) {
for (Iterator iterator = services.iterator(); iterator.hasNext();) {
ServiceElement serviceElement = (ServiceElement) iterator.next();
if(lipport.equals(serviceElement.ipport)) {
return true;
}
}
return false;
}
}
@@ -32,21 +32,21 @@ public class TCPConnection {
if (din != null)
din.close();
} catch (IOException e1) {
// TODO 自动生成的 catch 块
// TODO 自动生成的 catch 块
e1.printStackTrace();
}
try {
if (dout != null)
dout.close();
} catch (IOException e1) {
// TODO 自动生成的 catch 块
// TODO 自动生成的 catch 块
e1.printStackTrace();
}
try {
if (connect != null)
connect.close();
} catch (IOException e) {
// TODO 自动生成的 catch 块
// TODO 自动生成的 catch 块
e.printStackTrace();
}
connect = null;
@@ -21,7 +21,7 @@ public class TCPListener {
while(flag){
try {
Socket soce=servers.accept();
ThreadTool.makeVThreadIfSupport("¶Ë¿Ú¼àÌýÏß³Ì",()->{
ThreadTool.makeVThreadIfSupport("端口监听线程",()->{
con.accept(soce);
}).start();
} catch (IOException e) {
+2 -2
View File
@@ -32,11 +32,11 @@ public class TPanel extends JPanel{
setLayout(new BorderLayout(0, 0));
tname = new JLabel(name);
tname.setFont(new Font("ËÎÌå", Font.BOLD, 20));
tname.setFont(new Font("宋体", Font.BOLD, 20));
add(tname, BorderLayout.WEST);
targ = new JLabel();
targ.setFont(new Font("ËÎÌå", Font.PLAIN, 13));
targ.setFont(new Font("宋体", Font.PLAIN, 13));
targ.setHorizontalAlignment(SwingConstants.TRAILING);
targ.setForeground(Color.YELLOW);
add(targ, BorderLayout.CENTER);
+95 -5
View File
@@ -2,10 +2,13 @@ package org.kne.cloud.network.klalb;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.InetSocketAddress;
import java.net.Socket;
@@ -19,6 +22,7 @@ import java.util.Set;
import java.util.Vector;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
@@ -30,6 +34,34 @@ import org.kne.cloud.network.mport.IPPort;
public class Tunnel{
private String name;
private IPPort ipport;
private String frpc;
public String getFrpc() {
return frpc;
}
private Thread hook;
public void setFrpc(String frpc) {
this.frpc = frpc;
if(frpc!=null&&hook==null) {
hook=new Thread(()->{
finalize();
});
Runtime.getRuntime().addShutdownHook(hook);
}
}
@Override
protected void finalize() {
if(hook!=null) {
try {
Runtime.getRuntime().removeShutdownHook(hook);
}catch(Exception e) {
}
if(p!=null) {
System.out.println("frpc已关闭");
p.destroy();
}
}
}
private boolean state=false;
private TListener tlr;
@@ -87,9 +119,62 @@ public class Tunnel{
public String toString() {
return getName()+"$"+getIpport()+" "+delay/1000000;
}
private volatile Process p=null;
public Socket connectClientSocket() throws UnknownHostException, IOException {
if(frpc!=null) {
File f=new File("frpc");
f.mkdirs();
File inif=new File(f,"frpc.ini");
inif.createNewFile();
PrintStream ps=new PrintStream(inif);
ps.print(frpc);
ps.close();
AtomicBoolean ab=new AtomicBoolean(false);
Object lock=new Object();
if(p==null)
new Thread(()->{
try {
p = Runtime.getRuntime().exec("./frpc/frpc_windows_386.exe",null,f);
BufferedReader brd=new BufferedReader(new InputStreamReader( p.getInputStream()));
while(true) {
String r=brd.readLine();
if(r==null)
break;
System.err.println(r);
if(r.contains("start visitor success")) {
synchronized (lock) {
lock.notifyAll();
}
return;
}
}
ab.set(true);
synchronized (lock) {
lock.notifyAll();
}
} catch (IOException e) {
e.printStackTrace();
}
}).start();
synchronized (lock) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if(ab.get()) {
throw new IOException("frpc ERROR");
}
}
Socket socket=new Socket();
// socket.bind(new InetSocketAddress(new Random().nextInt(65535)+1));
socket.connect(getIpport().getSocketAddress(), Consts.CONNECT_TIMEOUT);
return socket;
}
@@ -140,22 +225,27 @@ public class Tunnel{
public AtomicLong getIM() {
return im;
}
PrintStream ndbg=null;
/*PrintStream ndbg=null;
private void initcdbg() {
try {
ndbg=new PrintStream(name+".csv");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}*/
public void updateTraffics(long timems) {
tlr.setTraffic(om.get(), im.get(), om.get()-om1, im.get()-im1);
/*
if(ndbg==null)
initcdbg();
ndbg.println((om.get()-om1)+ (im.get()-im1)+","+delay);
*/
om1=om.get();
im1=im.get();
}
public void destroyFrpc() {
if(p!=null) {
p.destroy();
}
}
}
@@ -22,8 +22,8 @@ public class PortMultiUse {
}
Scanner scn=new Scanner(f);
int remp=scn.nextInt();
System.out.println("端口复用程序V0.2");
System.out.println("开放端口:"+remp);
System.out.println("端口复用程序V0.2");
System.out.println("开放端口:"+remp);
while(scn.hasNext() ) {
String s=scn.next();
ServiceElement se=new ServiceElement(s);
@@ -32,7 +32,7 @@ public class PortMultiUse {
}
scn.close();
new PortRelay(remp,services).start();
System.out.println("提示:运行时输入reload可以重新加载配置文件,已经建立的TCP连接不受影响(暂不支持修改开放端口)");
System.out.println("提示:运行时输入reload可以重新加载配置文件,已经建立的TCP连接不受影响(暂不支持修改开放端口)");
Scanner scn2=new Scanner(System.in);
while(true) {
String command=scn2.next();
@@ -56,16 +56,16 @@ public class PortMultiUse {
}
private static void ept() {
System.out.println("请填写配置文件后再启动程序!");
System.out.println("格式:");
System.out.println("开放端口");
System.out.println("服务协议1$服务地址1$服务端口1");
System.out.println("服务协议2$服务地址2$服务端口2");
System.out.println("请填写配置文件后再启动程序!");
System.out.println("格式:");
System.out.println("开放端口");
System.out.println("服务协议1$服务地址1$服务端口1");
System.out.println("服务协议2$服务地址2$服务端口2");
System.out.println("......");
System.out.println("服务协议n$服务地址n$服务端口n");
System.out.println("默认服务地址$默认服务端口");
System.out.println("服务协议n$服务地址n$服务端口n");
System.out.println("默认服务地址$默认服务端口");
System.out.println("");
System.out.println("按照顺序从上向下匹配,若都不是则匹配最后一个");
System.out.println("按照顺序从上向下匹配,若都不是则匹配最后一个");
}
}
@@ -17,7 +17,7 @@ public class PortRelay {
this.services = services;
this.port = port;
ssc=new TCPListener(port);
System.out.println("已打开端口:" + port);
System.out.println("已打开端口:" + port);
}
public void start() throws IOException {
ssc.setCon((s)->{
@@ -44,7 +44,7 @@ public class PortRelay {
dinl=xdinl;
final DataOutputStream xdoutl =new DataOutputStream(sl.getOutputStream());
doutl=xdoutl;
Thread tl=ThreadTool.makeVThreadIfSupport("远程->本地 转发线程", ()->{
Thread tl=ThreadTool.makeVThreadIfSupport("远程->本地 转发线程", ()->{
try {
xdoutl.writeShort(n);
int len;
@@ -67,7 +67,7 @@ public class PortRelay {
}
}
});
Thread tr=ThreadTool.makeVThreadIfSupport("本地->远程 转发线程", ()->{
Thread tr=ThreadTool.makeVThreadIfSupport("本地->远程 转发线程", ()->{
try {
int len;
byte[]b=new byte[8192];
@@ -80,7 +80,7 @@ public class PortRelay {
try {
xdinl.close();
} catch (IOException e) {
// TODO 自动生成的 catch 块
// TODO 自动生成的 catch 块
e.printStackTrace();
}
if(xdout!=null)
@@ -38,7 +38,7 @@ public class ServiceElement {
}
}
public ServiceElement() {
// TODO 自动生成的构造函数存根
// TODO 自动生成的构造函数存根
}
@Override
public String toString() {
@@ -17,7 +17,7 @@ public class TCPListener {
while(flag){
try {
Socket soce=servers.accept();
ThreadTool.makeVThreadIfSupport("¶Ë¿Ú¼àÌýÏß³Ì",()->{
ThreadTool.makeVThreadIfSupport("端口监听线程",()->{
con.accept(soce);
}).start();
} catch (IOException e) {
@@ -21,7 +21,7 @@ public class ThreadTool {
}catch(Throwable e) {
//e.printStackTrace();
if(first) {
System.out.println("请使用java19以上版本以提高性能!");
System.out.println("请使用java19以上版本以提高性能!");
first=false;
}
return new Thread(r, name);