KLALB2.3
@@ -10,5 +10,7 @@
|
|||||||
<classpathentry kind="lib" path="lib/gson-2.1.jar"/>
|
<classpathentry kind="lib" path="lib/gson-2.1.jar"/>
|
||||||
<classpathentry kind="lib" path="lib/javassist.jar" sourcepath="C:/Users/ADMINI~1/AppData/Local/Temp/1/.org.sf.feeling.decompiler1686963856070/source/javassist-3.29.2-GA-sources.jar"/>
|
<classpathentry kind="lib" path="lib/javassist.jar" sourcepath="C:/Users/ADMINI~1/AppData/Local/Temp/1/.org.sf.feeling.decompiler1686963856070/source/javassist-3.29.2-GA-sources.jar"/>
|
||||||
<classpathentry kind="lib" path="lib/ini4j.jar"/>
|
<classpathentry kind="lib" path="lib/ini4j.jar"/>
|
||||||
|
<classpathentry kind="lib" path="lib/JFreeChart1.5.2.jar"/>
|
||||||
|
<classpathentry kind="lib" path="lib/toml4j-0.7.1.jar"/>
|
||||||
<classpathentry kind="output" path="bin"/>
|
<classpathentry kind="output" path="bin"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
|
|||||||
@@ -1,29 +1,79 @@
|
|||||||
[
|
[
|
||||||
{"Type":"KLALBController" ,
|
{"Type":"KLALBController" ,
|
||||||
"TCPListen" : "0.0.0.0:4567",
|
"TCPListen" : "0.0.0.0:4565",
|
||||||
|
"UDPListen" : "{UDP}0.0.0.0:4572",
|
||||||
"VirtualSocketName" : "KLALB_Stream",
|
"VirtualSocketName" : "KLALB_Stream",
|
||||||
"LineTable":["192.168.0.233:4569","192.168.1.233:4569"]
|
"LineTable":["43.248.189.107:65529",
|
||||||
|
"cn-bj-bgp-3.openfrp.top:65529",
|
||||||
|
"180.76.147.250:65529",
|
||||||
|
"cn-ah-dx-1.natfrp.cloud:65529",
|
||||||
|
"cn-nn-dx-1.natfrp.cloud:65529",
|
||||||
|
"cn-wh-dx-1.natfrp.cloud:65529",
|
||||||
|
"cn-zz-bgp-10.natfrp.cloud:23330",
|
||||||
|
"cn-zz-bgp-7.natfrp.cloud:33336",
|
||||||
|
"43.143.109.64:49965",
|
||||||
|
"frp.104300.xyz:49965",
|
||||||
|
"us.afrps.cn:49966",
|
||||||
|
"hk.afrps.cn:49966",
|
||||||
|
"la.afrps.cn:49966",
|
||||||
|
"frp.freefrp.net:49965",
|
||||||
|
"frp1.freefrp.net:49965",
|
||||||
|
"frp2.freefrp.net:49965",
|
||||||
|
"frp4.freefrp.net:49965",
|
||||||
|
"cn-he-plc-2.openfrp.top:4572",
|
||||||
|
"{UDP}cn-he-plc-2.openfrp.top:4572",
|
||||||
|
"frp-mom.top:22226",
|
||||||
|
"frp-man.top:36555",
|
||||||
|
"us-sjc-bgp-2.openfrp.top:36555",
|
||||||
|
"us-sjc-bgp-1.openfrp.top:36555",
|
||||||
|
"[240e:340:d856:b700:6d02:6a6a:f9fc:865b]:4572"]
|
||||||
},
|
},
|
||||||
{"Type":"SocketBridge" ,
|
{"Type":"SocketBridge" ,
|
||||||
"Listen" : "0.0.0.0:4569",
|
"Listen" : "0.0.0.0:4572",
|
||||||
|
"Bridge":{
|
||||||
|
"KLALB" : "SocketBridge",
|
||||||
|
"RDP":"SocketBridge",
|
||||||
|
"HTTP":"SocketBridge",
|
||||||
|
"HTTPS":"SocketBridge",
|
||||||
|
"DEFAULT":"MinecraftSocketBridge23332"
|
||||||
|
} ,
|
||||||
"Connect" : {
|
"Connect" : {
|
||||||
"KLALB" : "127.0.0.1:4567",
|
"KLALB" : "127.0.0.1:4565",
|
||||||
"RDP":"127.0.0.1:3389",
|
"RDP":"127.0.0.1:3389",
|
||||||
"HTTP":"127.0.0.1:5212",
|
"HTTP":"127.0.0.1:5212",
|
||||||
"HTTPS":"192.168.1.235:443",
|
"HTTPS":"192.168.1.235:443",
|
||||||
"DEFAULT":"127.0.0.1:36554"
|
"DEFAULT":"127.0.0.1:36555"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{"Type":"MinecraftSocketBridge" ,
|
{"Type":"SocketBridge" ,
|
||||||
"Listen" : "0.0.0.0:36554",
|
|
||||||
"Connect" : "127.0.0.1:36555"
|
|
||||||
},
|
|
||||||
{"Type":"MinecraftSocketBridge" ,
|
|
||||||
"Listen" : "{KLALB_Stream}[::0]:23332",
|
"Listen" : "{KLALB_Stream}[::0]:23332",
|
||||||
|
"Bridge":"MinecraftSocketBridge23332",
|
||||||
"Connect" : "127.0.0.1:36555"
|
"Connect" : "127.0.0.1:36555"
|
||||||
},
|
},
|
||||||
{ "Type":"SocketBridge" ,
|
{ "Type":"SocketBridge" ,
|
||||||
"Listen" : "{KLALB_Stream}[::0]:23333",
|
"Listen" : "{KLALB_Stream}[::0]:23333",
|
||||||
|
"Bridge":"SocketBridge",
|
||||||
"Connect" : "127.0.0.1:5212"
|
"Connect" : "127.0.0.1:5212"
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{"Type":"SocketBridge" ,
|
||||||
|
"Listen" : "0.0.0.0:25561",
|
||||||
|
"Bridge":{
|
||||||
|
"KLALB" : "SocketBridge",
|
||||||
|
"DEFAULT":"MinecraftSocketBridge23330"
|
||||||
|
} ,
|
||||||
|
"Connect" : {
|
||||||
|
"KLALB" : "127.0.0.1:4565",
|
||||||
|
"DEFAULT":"127.0.0.1:25562"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{"Type":"SocketBridge" ,
|
||||||
|
"Listen" : "{KLALB_Stream}[::0]:23330",
|
||||||
|
"Bridge":"MinecraftSocketBridge23330",
|
||||||
|
"Connect" : "127.0.0.1:25562"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
{UDP}192.168.1.233:4569
|
|
||||||
{UDP}192.168.0.233:4569
|
|
||||||
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
@@ -0,0 +1,74 @@
|
|||||||
|
package org.kne.cloud.clock;
|
||||||
|
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
|
public class AdjustedNanoClock {
|
||||||
|
private ReentrantLock lock=new ReentrantLock();
|
||||||
|
|
||||||
|
|
||||||
|
public ReentrantLock getLock() {
|
||||||
|
return lock;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private volatile long delta=0;
|
||||||
|
private volatile long accuracy=Long.MAX_VALUE;
|
||||||
|
private boolean unsetted=true;
|
||||||
|
public long getCurrentTime() {
|
||||||
|
return System.nanoTime()+delta;
|
||||||
|
}
|
||||||
|
public AdjustedNanoClock(long delta) {
|
||||||
|
super();
|
||||||
|
this.delta = delta;
|
||||||
|
}
|
||||||
|
public AdjustedNanoClock() {
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "AdjustedNanoClock [delta=" + delta + ", accuracy=" + accuracy + "]";
|
||||||
|
}
|
||||||
|
public long getDelta() {
|
||||||
|
return delta;
|
||||||
|
}
|
||||||
|
public void setDelta(long delta) {
|
||||||
|
this.delta = delta;
|
||||||
|
}
|
||||||
|
public void setCurrentTime(long curr) {
|
||||||
|
delta=curr-System.nanoTime();
|
||||||
|
}
|
||||||
|
public void setCurrentTime2(long curr) {
|
||||||
|
if(unsetted) {
|
||||||
|
unsetted=false;
|
||||||
|
delta=curr-System.nanoTime();
|
||||||
|
}else {
|
||||||
|
delta=(delta*9+ curr-System.nanoTime())/10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public long getAccuracy() {
|
||||||
|
return accuracy;
|
||||||
|
}
|
||||||
|
public void calibrate(long delta,long taccurace) {
|
||||||
|
if(accuracy==Long.MAX_VALUE||taccurace<= accuracy) {
|
||||||
|
accuracy=taccurace;
|
||||||
|
unsetted=false;
|
||||||
|
this.delta=delta;
|
||||||
|
//System.out.println(delta+" "+currentTime+" "+taccurace);
|
||||||
|
}else {
|
||||||
|
accuracy=(accuracy*9999+taccurace)/10000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void calibrate2(long delta,long taccurace) {
|
||||||
|
if(accuracy==Long.MAX_VALUE||taccurace<= accuracy) {
|
||||||
|
accuracy=taccurace;
|
||||||
|
if(unsetted) {
|
||||||
|
unsetted=false;
|
||||||
|
this.delta=delta;
|
||||||
|
}else {
|
||||||
|
this.delta=(this.delta*9+delta)/10;
|
||||||
|
}
|
||||||
|
//System.out.println(delta+" "+currentTime+" "+taccurace);
|
||||||
|
}else {
|
||||||
|
accuracy=(accuracy*9999+taccurace)/10000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package org.kne.cloud.clock;
|
||||||
|
|
||||||
|
public class ExponentialBackoffTimeClock {
|
||||||
|
|
||||||
|
private volatile long coolingTime=5000000000L;
|
||||||
|
|
||||||
|
{
|
||||||
|
resetCoolingTime();
|
||||||
|
}
|
||||||
|
public volatile long minCoolingTime=5000000000L,maxCoolingTime=300000000000L;
|
||||||
|
public ExponentialBackoffTimeClock(long minCoolingTime, long maxCoolingTime) {
|
||||||
|
super();
|
||||||
|
this.minCoolingTime = minCoolingTime;
|
||||||
|
this.maxCoolingTime = maxCoolingTime;
|
||||||
|
}
|
||||||
|
public ExponentialBackoffTimeClock() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
public long getCoolingTime() {
|
||||||
|
return coolingTime;
|
||||||
|
}
|
||||||
|
public void incCoolingTime() {
|
||||||
|
coolingTime<<=1;
|
||||||
|
if(coolingTime>maxCoolingTime) {
|
||||||
|
coolingTime=maxCoolingTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void resetCoolingTime() {
|
||||||
|
coolingTime=minCoolingTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package org.kne.cloud.clock;
|
||||||
|
|
||||||
|
public class ReliabilityBackoffTimeClock {
|
||||||
|
|
||||||
|
public volatile long maxCoolingTime=300000000000L;
|
||||||
|
public ReliabilityBackoffTimeClock(long maxCoolingTime) {
|
||||||
|
super();
|
||||||
|
this.maxCoolingTime = maxCoolingTime;
|
||||||
|
}
|
||||||
|
public ReliabilityBackoffTimeClock() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
public long getCoolingTime(double reliability) {
|
||||||
|
return (long) ((1.0-reliability)*maxCoolingTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,170 +7,359 @@ import java.net.DatagramSocket;
|
|||||||
import java.net.DatagramSocketImpl;
|
import java.net.DatagramSocketImpl;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.NetworkInterface;
|
||||||
|
import java.net.ServerSocket;
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
|
import java.net.SocketTimeoutException;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
import java.util.concurrent.ArrayBlockingQueue;
|
import java.util.concurrent.ArrayBlockingQueue;
|
||||||
|
import java.util.concurrent.BlockingQueue;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.Flow.Subscriber;
|
import java.util.concurrent.Flow.Subscriber;
|
||||||
|
import java.util.concurrent.locks.LockSupport;
|
||||||
|
|
||||||
public class DatagramServerSocket extends DatagramSocket {
|
import org.kne.cloud.network.klalb.ByteArrayPool;
|
||||||
private Map<SocketAddress,SubDatagramSocket> clients=new ConcurrentHashMap<>();
|
import org.kne.cloud.network.klalb.DATATPacket;
|
||||||
|
import org.kne.cloud.network.klalb.KLALBRemoteLine;
|
||||||
|
|
||||||
|
public class DatagramServerSocket implements java.io.Closeable{
|
||||||
|
public static final ByteArrayPool dataarraypool=new ByteArrayPool(100, 65535);
|
||||||
|
|
||||||
|
private boolean closed=false;
|
||||||
|
private boolean bound=false;
|
||||||
|
private DatagramSocketFactory dgsf;
|
||||||
|
private Set<DatagramDistributor> skts=new HashSet<>();
|
||||||
|
private final Object stateLock = new Object();
|
||||||
|
private BlockingQueue<DatagramSocket> recs;
|
||||||
|
private InetSocketAddress bindpoint;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public DatagramServerSocket() throws SocketException {
|
public DatagramServerSocket() throws SocketException {
|
||||||
super((SocketAddress)null);
|
this(new DefaultDatagramSocketFactory());
|
||||||
setReuseAddress(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected DatagramServerSocket(DatagramSocketImpl impl) throws SocketException {
|
protected DatagramServerSocket(DatagramSocketFactory impl) throws SocketException {
|
||||||
super(impl);
|
this.dgsf=impl;
|
||||||
setReuseAddress(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public DatagramServerSocket(int port, InetAddress laddr) throws SocketException {
|
public DatagramServerSocket(int port, InetAddress laddr) throws SocketException {
|
||||||
super((SocketAddress)null);
|
this(new DefaultDatagramSocketFactory());
|
||||||
setReuseAddress(true);
|
|
||||||
bind(new InetSocketAddress(laddr, port));
|
bind(new InetSocketAddress(laddr, port));
|
||||||
}
|
}
|
||||||
|
|
||||||
public DatagramServerSocket(int port) throws SocketException {
|
public DatagramServerSocket(int port) throws SocketException {
|
||||||
super((SocketAddress)null);
|
this(new DefaultDatagramSocketFactory());
|
||||||
setReuseAddress(true);
|
|
||||||
bind(new InetSocketAddress(port));
|
bind(new InetSocketAddress(port));
|
||||||
}
|
}
|
||||||
|
|
||||||
public DatagramServerSocket(SocketAddress bindaddr) throws SocketException {
|
public DatagramServerSocket(SocketAddress bindaddr) throws SocketException {
|
||||||
super((SocketAddress)null);
|
this(new DefaultDatagramSocketFactory());
|
||||||
setReuseAddress(true);
|
|
||||||
bind(bindaddr);
|
bind(bindaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DatagramServerSocket(int port, int backlog) throws SocketException {
|
public DatagramServerSocket(int port, int backlog) throws SocketException {
|
||||||
super((SocketAddress)null);
|
this(new DefaultDatagramSocketFactory());
|
||||||
setReuseAddress(true);
|
|
||||||
bind(new InetSocketAddress(port));
|
bind(new InetSocketAddress(port));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized void send(DatagramPacket p) throws IOException {
|
|
||||||
// TODO 自动生成的方法存根
|
|
||||||
super.send(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized void receive(DatagramPacket p) throws IOException {
|
|
||||||
// TODO 自动生成的方法存根
|
|
||||||
super.receive(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
public DatagramServerSocket(int port, int backlog, InetAddress laddr) throws SocketException {
|
public DatagramServerSocket(int port, int backlog, InetAddress laddr) throws SocketException {
|
||||||
super((SocketAddress)null);
|
this(new DefaultDatagramSocketFactory());
|
||||||
setReuseAddress(true);
|
|
||||||
bind(new InetSocketAddress(laddr, port));
|
bind(new InetSocketAddress(laddr, port));
|
||||||
}
|
}
|
||||||
public DatagramSocket accept()throws IOException{
|
public void bind(SocketAddress endpoint) throws SocketException {
|
||||||
if (isClosed())
|
bind(endpoint, 50);
|
||||||
|
}
|
||||||
|
public void bind(SocketAddress endpoint, int backlog) throws SocketException {
|
||||||
|
if (isClosed())
|
||||||
throw new SocketException("Socket is closed");
|
throw new SocketException("Socket is closed");
|
||||||
if (!isBound())
|
if (isBound())
|
||||||
throw new SocketException("Socket is not bound yet");
|
throw new SocketException("Already bound");
|
||||||
DatagramPacket dp=new DatagramPacket(new byte[65535], 65535);
|
if (endpoint == null)
|
||||||
do {
|
endpoint = new InetSocketAddress(0);
|
||||||
receive(dp);
|
if (!(endpoint instanceof InetSocketAddress epoint))
|
||||||
System.out.println(dp);
|
throw new IllegalArgumentException("Unsupported address type");
|
||||||
}while(clients.containsKey(dp.getSocketAddress()));
|
if (epoint.isUnresolved())
|
||||||
System.out.println("accept");
|
throw new SocketException("Unresolved address");
|
||||||
SubDatagramSocket re=new SubDatagramSocket((SocketAddress)null);
|
if (backlog < 1)
|
||||||
re.dp=dp;
|
backlog = 50;
|
||||||
re.setReuseAddress(true);
|
|
||||||
re.bind(new InetSocketAddress(InetAddress.getByName("192.168.0.233"), getLocalPort()));
|
@SuppressWarnings("removal")
|
||||||
re.connect(dp.getSocketAddress());
|
SecurityManager security = System.getSecurityManager();
|
||||||
return re;
|
if (security != null)
|
||||||
/* loop:while(true) {
|
security.checkListen(epoint.getPort());
|
||||||
receive(dp);
|
|
||||||
SocketAddress isa= dp.getSocketAddress() ;
|
synchronized (stateLock) {
|
||||||
synchronized (clients) {
|
if (closed)
|
||||||
for (Iterator<SubDatagramSocket> iterator = clients.iterator(); iterator.hasNext();) {
|
throw new SocketException("Socket is closed");
|
||||||
SubDatagramSocket subDatagramSocket = (SubDatagramSocket) iterator.next();
|
if (bound)
|
||||||
if(subDatagramSocket.getRemoteSocketAddress().equals(isa)) {
|
throw new SocketException("Already bound");
|
||||||
DatagramPacket dpx=dp;
|
bind0(epoint);
|
||||||
dp=new DatagramPacket(new byte[65535], 65535);
|
recs=new ArrayBlockingQueue<DatagramSocket>(backlog);
|
||||||
subDatagramSocket.getFstq().offer(dpx);
|
bound = true;
|
||||||
continue loop;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void bind0(InetSocketAddress epoint) throws SocketException {
|
||||||
|
bindpoint=epoint;
|
||||||
|
if(epoint.getAddress().isAnyLocalAddress()) {
|
||||||
|
Enumeration<NetworkInterface>eu= NetworkInterface.getNetworkInterfaces();
|
||||||
|
while (eu.hasMoreElements()) {
|
||||||
|
NetworkInterface networkInterface = (NetworkInterface) eu.nextElement();
|
||||||
|
if(networkInterface.isUp()) {
|
||||||
|
//System.out.println(networkInterface+" "+networkInterface.isUp());
|
||||||
|
Enumeration<InetAddress>ei= networkInterface.getInetAddresses();
|
||||||
|
while (ei.hasMoreElements()) {
|
||||||
|
InetAddress inetAddress = (InetAddress) ei.nextElement();
|
||||||
|
DatagramDistributor dd=new DatagramDistributor(new InetSocketAddress(inetAddress, epoint.getPort()));
|
||||||
|
skts.add(dd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DatagramPacket dpx=dp;
|
|
||||||
dp=new DatagramPacket(new byte[65535], 65535);
|
}else {
|
||||||
SubDatagramSocket sds=new SubDatagramSocket(isa);
|
DatagramDistributor dd=new DatagramDistributor(epoint);
|
||||||
sds.getFstq().add(dpx);
|
skts.add(dd);
|
||||||
return sds;
|
}
|
||||||
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
private class SubDatagramSocket extends DatagramSocket{
|
private class DatagramDistributor implements Runnable{
|
||||||
|
private Map<SocketAddress,SubDatagramSocket> clients=new ConcurrentHashMap<>();
|
||||||
|
|
||||||
DatagramPacket dp;
|
private InetSocketAddress epoint;
|
||||||
|
private DatagramSocket datagramSocket;
|
||||||
public SubDatagramSocket() throws SocketException {
|
public DatagramDistributor(InetSocketAddress epoint) throws SocketException {
|
||||||
super();
|
this.epoint=epoint;
|
||||||
|
datagramSocket=new DatagramSocket(epoint);
|
||||||
|
ThreadTool.makeVDaemonThreadIfSupport("Datagram Distribute Thread", this).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected SubDatagramSocket(DatagramSocketImpl impl) {
|
public DatagramSocket getDatagramSocket() {
|
||||||
super(impl);
|
return datagramSocket;
|
||||||
}
|
|
||||||
|
|
||||||
public SubDatagramSocket(int port, InetAddress laddr) throws SocketException {
|
|
||||||
super(port, laddr);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SubDatagramSocket(int port) throws SocketException {
|
|
||||||
super(port);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SubDatagramSocket(SocketAddress bindaddr) throws SocketException {
|
|
||||||
super(bindaddr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void connect(InetAddress address, int port) {
|
public void run() {
|
||||||
super.connect(address, port);
|
try {
|
||||||
clients.put(new InetSocketAddress(address, port),this);
|
while(true) {
|
||||||
|
byte[]data=dataarraypool.borrow();
|
||||||
|
DatagramPacket dp=new DatagramPacket(data,data.length);
|
||||||
|
datagramSocket.receive(dp);
|
||||||
|
//System.out.println("get:"+dp);
|
||||||
|
SubDatagramSocket sdds=clients.get(dp.getSocketAddress());
|
||||||
|
if(sdds==null) {
|
||||||
|
if(recs.remainingCapacity()>1) {
|
||||||
|
sdds=new SubDatagramSocket(epoint, (InetSocketAddress) dp.getSocketAddress(),this );
|
||||||
|
if(recs.offer(sdds))
|
||||||
|
clients.put(dp.getSocketAddress(), sdds);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if(sdds!=null) {
|
||||||
|
//System.out.println("give:"+dp);
|
||||||
|
sdds.givePacket(dp);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
// TODO 自动生成的 catch 块
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void removeClient(SubDatagramSocket subDatagramSocket) {
|
||||||
public void connect(SocketAddress addr) throws SocketException {
|
clients.remove(subDatagramSocket.getRemoteSocketAddress());
|
||||||
super.connect(addr);
|
}
|
||||||
clients.put(addr,this);
|
|
||||||
|
}
|
||||||
|
public DatagramSocket accept()throws IOException{
|
||||||
|
while(true) {
|
||||||
|
if(isClosed())
|
||||||
|
throw new SocketException("DatagramServerSocket closed");
|
||||||
|
if (!isBound())
|
||||||
|
throw new SocketException("DatagramServerSocket is not bound yet");
|
||||||
|
DatagramSocket sds= recs.poll();
|
||||||
|
if(sds!=null) {
|
||||||
|
return sds;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Thread.sleep(1);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private boolean isClosed() {
|
||||||
|
return closed;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isBound() {
|
||||||
|
return bound;
|
||||||
|
}
|
||||||
|
public class SubDatagramSocket extends DatagramSocket{
|
||||||
|
private DatagramDistributor parent;
|
||||||
|
private InetSocketAddress local;
|
||||||
|
private InetSocketAddress remote;
|
||||||
|
private boolean closed=false;
|
||||||
|
private int timeout=0;
|
||||||
|
private BlockingQueue<DatagramPacket> recs=new ArrayBlockingQueue(100);
|
||||||
|
private volatile Thread t;
|
||||||
|
private void unwait() {
|
||||||
|
if(t!=null)
|
||||||
|
LockSupport.unpark(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubDatagramSocket(InetSocketAddress local,InetSocketAddress remote,DatagramDistributor datagramDistributor) throws SocketException {
|
||||||
|
super((SocketAddress)null);
|
||||||
|
this.local=local;
|
||||||
|
this.remote=remote;
|
||||||
|
this.parent=datagramDistributor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean givePacket(DatagramPacket dp) {
|
||||||
|
boolean b=recs.offer(dp);
|
||||||
|
unwait();
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
public DatagramPacket receive()throws IOException{
|
||||||
|
long start=System.nanoTime();
|
||||||
|
while(true) {
|
||||||
|
if(closed) {
|
||||||
|
throw new SocketException("DatagramSocket closed");
|
||||||
|
}
|
||||||
|
DatagramPacket dp=recs.poll();
|
||||||
|
if(dp!=null) {
|
||||||
|
|
||||||
|
return dp;
|
||||||
|
}
|
||||||
|
if(timeout!=0) {
|
||||||
|
long dms=(System.nanoTime()-start)/1000000;
|
||||||
|
if(dms>timeout)
|
||||||
|
throw new SocketTimeoutException("Receive Time Out");
|
||||||
|
}
|
||||||
|
t=Thread.currentThread();
|
||||||
|
LockSupport.parkNanos(1000000);
|
||||||
|
}
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
public void receive(DatagramPacket p) throws IOException {
|
public void receive(DatagramPacket p) throws IOException {
|
||||||
if(dp!=null) {
|
DatagramPacket dp=null;
|
||||||
p.setLength(dp.getLength());
|
long start=System.nanoTime();
|
||||||
System.arraycopy(dp.getData(), dp.getOffset(), p.getData(), p.getOffset(), dp.getLength());
|
while(true) {
|
||||||
dp=null;
|
if(closed) {
|
||||||
}else {
|
throw new SocketException("DatagramSocket closed");
|
||||||
super.receive(p);
|
}
|
||||||
}
|
dp=recs.poll();
|
||||||
|
if(dp!=null) {
|
||||||
|
p.setLength(dp.getLength());
|
||||||
|
System.arraycopy(dp.getData(), dp.getOffset(), p.getData(), p.getOffset(), dp.getLength());
|
||||||
|
dataarraypool.back(dp.getData());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(timeout!=0) {
|
||||||
|
long dms=(System.nanoTime()-start)/1000000;
|
||||||
|
if(dms>timeout)
|
||||||
|
throw new SocketTimeoutException("Receive Time Out");
|
||||||
|
}
|
||||||
|
t=Thread.currentThread();
|
||||||
|
LockSupport.parkNanos(1000000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void send(DatagramPacket p) throws IOException {
|
||||||
|
p.setSocketAddress(remote);
|
||||||
|
parent.getDatagramSocket().send(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void disconnect() {
|
public SocketAddress getRemoteSocketAddress() {
|
||||||
super.disconnect();
|
return remote;
|
||||||
SocketAddress sa=getRemoteSocketAddress();
|
|
||||||
if(sa!=null)
|
|
||||||
clients.remove(sa);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close() {
|
@Override
|
||||||
super.close();
|
public InetAddress getInetAddress() {
|
||||||
SocketAddress sa=getRemoteSocketAddress();
|
return remote.getAddress();
|
||||||
if(sa!=null)
|
|
||||||
clients.remove(sa);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPort() {
|
||||||
|
return remote.getPort();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SocketAddress getLocalSocketAddress() {
|
||||||
|
return local;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InetAddress getLocalAddress() {
|
||||||
|
return local.getAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getLocalPort() {
|
||||||
|
return local.getPort();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSoTimeout(int timeout) throws SocketException {
|
||||||
|
this.timeout=timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSoTimeout() throws SocketException {
|
||||||
|
return timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
if(!closed)
|
||||||
|
parent.removeClient(this);
|
||||||
|
closed=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isClosed() {
|
||||||
|
return closed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
closed=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SocketAddress getLocalSocketAddress() {
|
||||||
|
return bindpoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public InetAddress getLocalAddress() {
|
||||||
|
if(bindpoint==null)
|
||||||
|
return null;
|
||||||
|
else
|
||||||
|
return bindpoint.getAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLocalPort() {
|
||||||
|
if(bindpoint==null)
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
return bindpoint.getPort();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ public class DatagramSocketListener implements Closeable,AutoCloseable{
|
|||||||
if(serverSocket==null)
|
if(serverSocket==null)
|
||||||
serverSocket=multipurposeSocketAddress.listenDatagramServerSocket();
|
serverSocket=multipurposeSocketAddress.listenDatagramServerSocket();
|
||||||
//new Thread(r).start();
|
//new Thread(r).start();
|
||||||
ThreadTool.makeVThreadIfSupport("端口监听线程",r).start();
|
ThreadTool.makePThreadIfSupport("端口监听线程",r).start();
|
||||||
}
|
}
|
||||||
public void close() {
|
public void close() {
|
||||||
flag=false;
|
flag=false;
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package org.kne.cloud.network;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.Inet6Address;
|
||||||
|
import java.net.Socket;
|
||||||
|
|
||||||
|
import org.kne.cloud.network.klalb.KLALBVirtualSocket;
|
||||||
|
import org.kne.cloud.network.minecraft.KLALBJsonMotdInserter;
|
||||||
|
import org.kne.cloud.network.minecraft.MinecraftSocketBridge;
|
||||||
|
|
||||||
|
public class DefaultMinecraftSocketBridgeFactory extends SocketBridgeFactory {
|
||||||
|
private Inet6Address vaddr;
|
||||||
|
private int vport;
|
||||||
|
public DefaultMinecraftSocketBridgeFactory(Inet6Address vaddr, int vport) {
|
||||||
|
super();
|
||||||
|
this.vaddr = vaddr;
|
||||||
|
this.vport = vport;
|
||||||
|
}
|
||||||
|
public Inet6Address getVaddr() {
|
||||||
|
return vaddr;
|
||||||
|
}
|
||||||
|
public int getVport() {
|
||||||
|
return vport;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SocketBridge createBridge(Socket a, Socket b) throws IOException {
|
||||||
|
if(a instanceof KLALBVirtualSocket) {
|
||||||
|
KLALBVirtualSocket klv=(KLALBVirtualSocket) a;
|
||||||
|
klv.setCompress(1);
|
||||||
|
}
|
||||||
|
if(b instanceof KLALBVirtualSocket) {
|
||||||
|
KLALBVirtualSocket klv=(KLALBVirtualSocket) b;
|
||||||
|
klv.setCompress(1);
|
||||||
|
}
|
||||||
|
MinecraftSocketBridge msb=new MinecraftSocketBridge(a, b);
|
||||||
|
msb.getBridgeBA().getTransformers().add(new KLALBJsonMotdInserter(()->{return vaddr;},()->{return vport;}));
|
||||||
|
return msb;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package org.kne.cloud.network;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.nio.channels.ServerSocketChannel;
|
||||||
|
|
||||||
|
public class DefaultServerSocketChannelFactory extends ServerSocketChannelFactory {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServerSocketChannel createServerSocketChannel() throws IOException {
|
||||||
|
return ServerSocketChannel.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServerSocketChannel createServerSocketChannel(int port) throws IOException {
|
||||||
|
ServerSocketChannel ssc=ServerSocketChannel.open();
|
||||||
|
ssc.bind(new InetSocketAddress(port));
|
||||||
|
return ssc;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServerSocketChannel createServerSocketChannel(int port, int backlog) throws IOException {
|
||||||
|
ServerSocketChannel ssc=ServerSocketChannel.open();
|
||||||
|
ssc.bind(new InetSocketAddress(port),backlog);
|
||||||
|
return ssc;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServerSocketChannel createServerSocketChannel(int port, int backlog, InetAddress ifAddress)
|
||||||
|
throws IOException {
|
||||||
|
ServerSocketChannel ssc=ServerSocketChannel.open();
|
||||||
|
ssc.bind(new InetSocketAddress(ifAddress,port),backlog);
|
||||||
|
return ssc;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package org.kne.cloud.network;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.Socket;
|
||||||
|
|
||||||
|
public class DefaultSocketBridgeFactory extends SocketBridgeFactory {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SocketBridge createBridge(Socket a, Socket b) throws IOException {
|
||||||
|
return new SocketBridge(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package org.kne.cloud.network;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.nio.channels.SocketChannel;
|
||||||
|
|
||||||
|
public class DefaultSocketChannelBridgeFactory extends SocketChannelBridgeFactory {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SocketChannelBridge createBridge(SocketChannel a, SocketChannel b) throws IOException {
|
||||||
|
return new SocketChannelBridge(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package org.kne.cloud.network;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.nio.channels.SocketChannel;
|
||||||
|
|
||||||
|
public class DefaultSocketChannelFactory extends SocketChannelFactory {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SocketChannel createSocketChannel() throws IOException {
|
||||||
|
return SocketChannel.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SocketChannel createSocketChannel(String paramString, int paramInt) throws IOException {
|
||||||
|
SocketChannel conn=createSocketChannel();
|
||||||
|
conn.connect(new InetSocketAddress(paramString, paramInt));
|
||||||
|
return conn;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SocketChannel createSocketChannel(InetAddress paramInetAddress, int paramInt) throws IOException {
|
||||||
|
SocketChannel conn=createSocketChannel();
|
||||||
|
conn.connect(new InetSocketAddress(paramInetAddress, paramInt));
|
||||||
|
return conn;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SocketChannel createSocketChannel(String paramString, int paramInt1, InetAddress paramInetAddress,
|
||||||
|
int paramInt2) throws IOException, UnknownHostException {
|
||||||
|
SocketChannel conn=createSocketChannel();
|
||||||
|
conn.bind(new InetSocketAddress(paramInetAddress, paramInt2));
|
||||||
|
conn.connect(new InetSocketAddress(paramString, paramInt1));
|
||||||
|
return conn;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SocketChannel createSocketChannel(InetAddress paramInetAddress1, int paramInt1,
|
||||||
|
InetAddress paramInetAddress2, int paramInt2) throws IOException {
|
||||||
|
SocketChannel conn=createSocketChannel();
|
||||||
|
conn.bind(new InetSocketAddress(paramInetAddress2, paramInt2));
|
||||||
|
conn.connect(new InetSocketAddress(paramInetAddress1, paramInt1));
|
||||||
|
return conn;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,172 +0,0 @@
|
|||||||
package org.kne.cloud.network;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.Reader;
|
|
||||||
import java.net.Inet6Address;
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.net.Socket;
|
|
||||||
import java.net.UnknownHostException;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Hashtable;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
import org.kne.cloud.network.klalb.KLALBController;
|
|
||||||
import org.kne.cloud.network.klalb.KLALBController.KLALBSocketType;
|
|
||||||
import org.kne.cloud.network.klalb.KLALBRemoteLine;
|
|
||||||
import org.kne.cloud.network.klalb.StreamKLALBPacketLink;
|
|
||||||
import org.kne.cloud.network.minecraft.KLALBJsonMotdInserter;
|
|
||||||
import org.kne.cloud.network.minecraft.MinecraftSocketToSocketProxy;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import com.google.gson.JsonArray;
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import com.google.gson.JsonParser;
|
|
||||||
|
|
||||||
public class KLALBProxyConfigJsonExecuter {
|
|
||||||
private Set<Proxy> proxys=new HashSet<>();
|
|
||||||
private KLALBController klalbController;
|
|
||||||
public Set<Proxy> getProxys() {
|
|
||||||
return proxys;
|
|
||||||
}
|
|
||||||
public KLALBController getKlalbController() {
|
|
||||||
return klalbController;
|
|
||||||
}
|
|
||||||
public KLALBProxyConfigJsonExecuter(Reader json) {
|
|
||||||
loadConfigJson(json);
|
|
||||||
}
|
|
||||||
public KLALBProxyConfigJsonExecuter(String json) {
|
|
||||||
loadConfigJson(json);
|
|
||||||
}
|
|
||||||
|
|
||||||
public KLALBProxyConfigJsonExecuter(JsonElement json) {
|
|
||||||
loadConfigJson(json);
|
|
||||||
}
|
|
||||||
public KLALBProxyConfigJsonExecuter(File jsonFile) throws IOException {
|
|
||||||
loadConfigJson(jsonFile);
|
|
||||||
}
|
|
||||||
public KLALBProxyConfigJsonExecuter() {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void loadConfigJson(File jsonFile) throws IOException {
|
|
||||||
FileReader fr = null;
|
|
||||||
try {
|
|
||||||
fr=new FileReader(jsonFile);
|
|
||||||
loadConfigJson(fr);
|
|
||||||
}finally {
|
|
||||||
if(fr!=null)
|
|
||||||
fr.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
public void loadConfigJson(String json) {
|
|
||||||
loadConfigJson(new JsonParser().parse(json));
|
|
||||||
}
|
|
||||||
public void loadConfigJson(Reader json) {
|
|
||||||
loadConfigJson(new JsonParser().parse(json));
|
|
||||||
}
|
|
||||||
public void loadConfigJson(JsonElement json) {
|
|
||||||
JsonArray jobj=(JsonArray) json;
|
|
||||||
jobj.forEach((val)->{
|
|
||||||
solveEntry((JsonObject) val);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
protected void solveEntry(JsonObject entry){
|
|
||||||
switch (entry.get("Type").getAsString()) {
|
|
||||||
case "KLALBController":
|
|
||||||
JsonElement vase= entry.get("VirtualAddress");
|
|
||||||
if(vase!=null) {
|
|
||||||
try {
|
|
||||||
klalbController=new KLALBController((Inet6Address) InetAddress.getByName(vase.getAsString()));
|
|
||||||
} catch (UnknownHostException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}else {
|
|
||||||
klalbController=new KLALBController();
|
|
||||||
}
|
|
||||||
JsonElement vsne=entry.get("VirtualSocketName");
|
|
||||||
//if(vsne!=null) {
|
|
||||||
MultipurposeSocketAddress.getSocketTypeRegister().put(vsne.getAsString(), klalbController.getSocketType());
|
|
||||||
//}
|
|
||||||
JsonElement tcple=entry.get("TCPListen");
|
|
||||||
if(tcple!=null) {
|
|
||||||
MultipurposeSocketAddress mpsa=new MultipurposeSocketAddress(tcple.getAsString());
|
|
||||||
SocketListener tcpl = null;
|
|
||||||
try {
|
|
||||||
tcpl = new SocketListener(mpsa);
|
|
||||||
|
|
||||||
tcpl.setCon((soc)->{
|
|
||||||
|
|
||||||
KLALBRemoteLine krs=null;
|
|
||||||
try {
|
|
||||||
krs = new KLALBRemoteLine(new StreamKLALBPacketLink(soc));
|
|
||||||
klalbController.addRemoteLine(krs);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
} catch (IOException e1) {
|
|
||||||
e1.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
JsonElement linele=entry.get("LineTable");
|
|
||||||
if(linele!=null) {
|
|
||||||
JsonArray jary=(JsonArray)linele;
|
|
||||||
StringBuilder sb=new StringBuilder();
|
|
||||||
jary.forEach((aline)->{
|
|
||||||
sb.append(aline.getAsString());
|
|
||||||
sb.append('\n');
|
|
||||||
});
|
|
||||||
klalbController.setSelflineTableSupplier(()->{return sb.toString();});
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "SocketBridge":
|
|
||||||
HostPortMap mapp=new HostPortMap();
|
|
||||||
|
|
||||||
MultipurposeSocketAddress l=new MultipurposeSocketAddress(entry.get("Listen").getAsString());
|
|
||||||
MultipurposeSocketAddress r=getDefault(entry.get("Connect"),mapp);
|
|
||||||
try {
|
|
||||||
proxys.add(new SocketToSocketProxy(l ,new MultipurposeSocketAddress("0.0.0.0:0"), r,mapp));
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "MinecraftSocketBridge":
|
|
||||||
|
|
||||||
HostPortMap mapp2=new HostPortMap();
|
|
||||||
MultipurposeSocketAddress l2=new MultipurposeSocketAddress(entry.get("Listen").getAsString());
|
|
||||||
MultipurposeSocketAddress r2=getDefault(entry.get("Connect"),mapp2);
|
|
||||||
try {
|
|
||||||
MinecraftSocketToSocketProxy mcp=new MinecraftSocketToSocketProxy(l2 ,new MultipurposeSocketAddress("0.0.0.0:0"), r2,mapp2);
|
|
||||||
//if(MultipurposeSocketAddress.getSocketTypeRegister().get( l2.getType()) instanceof KLALBSocketType )
|
|
||||||
mcp.getTransformersBA().add(new KLALBJsonMotdInserter(()->{return klalbController.getSelf();},()->{return 23332;}));
|
|
||||||
proxys.add(mcp);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private MultipurposeSocketAddress getDefault(JsonElement jsonElement, HostPortMap mapp) {
|
|
||||||
if(jsonElement instanceof JsonObject) {
|
|
||||||
JsonObject jobj=(JsonObject) jsonElement;
|
|
||||||
jobj.entrySet().forEach((en)->{
|
|
||||||
mapp.put(en.getKey(), new MultipurposeSocketAddress( en.getValue().getAsString()));
|
|
||||||
});
|
|
||||||
return mapp.get("DEFAULT");
|
|
||||||
}else {
|
|
||||||
return new MultipurposeSocketAddress(jsonElement.getAsString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -10,8 +10,9 @@ import java.net.ServerSocket;
|
|||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
|
import java.nio.channels.ServerSocketChannel;
|
||||||
|
import java.nio.channels.SocketChannel;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import javax.net.ServerSocketFactory;
|
import javax.net.ServerSocketFactory;
|
||||||
import javax.net.SocketFactory;
|
import javax.net.SocketFactory;
|
||||||
@@ -20,11 +21,11 @@ public class MultipurposeSocketAddress implements Serializable{
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private static Map<String,SocketType> socketTypeRegister=new HashMap<>();
|
private static final Map<String,SocketType> socketTypeRegister=new HashMap<>();
|
||||||
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
socketTypeRegister.put("TCP", new SocketType(new DefaultSocketFactory(), new DefaultServerSocketFactory()));
|
socketTypeRegister.put("TCP", new SocketType(new DefaultSocketFactory(), new DefaultServerSocketFactory(),new DefaultSocketChannelFactory(),new DefaultServerSocketChannelFactory()));
|
||||||
socketTypeRegister.put("UDP", new SocketType(new DefaultDatagramSocketFactory(),new DefaultDatagramServerSocketFactory()));
|
socketTypeRegister.put("UDP", new SocketType(new DefaultDatagramSocketFactory(),new DefaultDatagramServerSocketFactory()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,6 +128,11 @@ public class MultipurposeSocketAddress implements Serializable{
|
|||||||
}
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public Socket connectSocket(InetAddress bindip,int bindport,int timeout) throws UnknownHostException, IOException {
|
public Socket connectSocket(InetAddress bindip,int bindport,int timeout) throws UnknownHostException, IOException {
|
||||||
SocketFactory sf=socketTypeRegister.get(type).getSocketFactory();
|
SocketFactory sf=socketTypeRegister.get(type).getSocketFactory();
|
||||||
if(sf==null) {
|
if(sf==null) {
|
||||||
@@ -166,6 +172,69 @@ public class MultipurposeSocketAddress implements Serializable{
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private static TimeoutTimer tmoTimer=new TimeoutTimer();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public SocketChannel connectSocketChannel(InetAddress bindip,int bindport,int timeout) throws UnknownHostException, IOException {
|
||||||
|
SocketChannelFactory sf=socketTypeRegister.get(type).getSocketChannelFactory();
|
||||||
|
if(sf==null) {
|
||||||
|
throw new UnsupportedOperationException("Socket Unsupported");
|
||||||
|
}
|
||||||
|
SocketChannel s=sf.createSocketChannel();
|
||||||
|
s.bind(new InetSocketAddress(bindip, bindport));
|
||||||
|
TimerTask tt=tmoTimer.createTimeOutTask(s, timeout);
|
||||||
|
try {
|
||||||
|
s.connect(new InetSocketAddress(host, port));
|
||||||
|
}finally {
|
||||||
|
if(tt!=null)
|
||||||
|
tt.cancel();
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
public SocketChannel connectSocketChannel(InetAddress bindip,int bindport) throws UnknownHostException, IOException {
|
||||||
|
SocketChannelFactory sf=socketTypeRegister.get(type).getSocketChannelFactory();
|
||||||
|
if(sf==null) {
|
||||||
|
throw new UnsupportedOperationException("Socket Unsupported");
|
||||||
|
}
|
||||||
|
SocketChannel s=sf.createSocketChannel();
|
||||||
|
s.bind(new InetSocketAddress(bindip, bindport));
|
||||||
|
s.connect(new InetSocketAddress(host, port));
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
public SocketChannel connectSocketChannel() throws UnknownHostException, IOException {
|
||||||
|
SocketChannelFactory sf=socketTypeRegister.get(type).getSocketChannelFactory();
|
||||||
|
if(sf==null) {
|
||||||
|
throw new UnsupportedOperationException("Socket Unsupported");
|
||||||
|
}
|
||||||
|
SocketChannel s=sf.createSocketChannel();
|
||||||
|
s.connect(new InetSocketAddress(host, port));
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
public SocketChannel connectSocketChannel(int timeout) throws UnknownHostException, IOException {
|
||||||
|
SocketChannelFactory sf=socketTypeRegister.get(type).getSocketChannelFactory();
|
||||||
|
if(sf==null) {
|
||||||
|
throw new UnsupportedOperationException("Socket Unsupported");
|
||||||
|
}
|
||||||
|
SocketChannel s=sf.createSocketChannel();
|
||||||
|
|
||||||
|
TimerTask tt=tmoTimer.createTimeOutTask(s, timeout);
|
||||||
|
try {
|
||||||
|
s.connect(new InetSocketAddress(host, port));
|
||||||
|
}finally {
|
||||||
|
if(tt!=null)
|
||||||
|
tt.cancel();
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public ServerSocket listenServerSocket() throws UnknownHostException, IOException {
|
public ServerSocket listenServerSocket() throws UnknownHostException, IOException {
|
||||||
ServerSocketFactory srf=socketTypeRegister.get(type).getServerSocketFactory();
|
ServerSocketFactory srf=socketTypeRegister.get(type).getServerSocketFactory();
|
||||||
if(srf==null) {
|
if(srf==null) {
|
||||||
@@ -182,6 +251,26 @@ public class MultipurposeSocketAddress implements Serializable{
|
|||||||
ServerSocket sk=srf.createServerSocket(port, backlog, InetAddress.getByName(host));
|
ServerSocket sk=srf.createServerSocket(port, backlog, InetAddress.getByName(host));
|
||||||
return sk;
|
return sk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public ServerSocketChannel listenServerSocketChannel() throws UnknownHostException, IOException {
|
||||||
|
ServerSocketChannelFactory srf=socketTypeRegister.get(type).getServerSocketChannelFactory();
|
||||||
|
if(srf==null) {
|
||||||
|
throw new UnsupportedOperationException("ServerSocket Unsupported");
|
||||||
|
}
|
||||||
|
ServerSocketChannel sk=srf.createServerSocketChannel(port, 50, InetAddress.getByName(host));
|
||||||
|
return sk;
|
||||||
|
}
|
||||||
|
public ServerSocketChannel listenServerSocketChannel(int backlog) throws UnknownHostException, IOException {
|
||||||
|
ServerSocketChannelFactory srf=socketTypeRegister.get(type).getServerSocketChannelFactory();
|
||||||
|
if(srf==null) {
|
||||||
|
throw new UnsupportedOperationException("ServerSocket Unsupported");
|
||||||
|
}
|
||||||
|
ServerSocketChannel sk=srf.createServerSocketChannel(port, backlog, InetAddress.getByName(host));
|
||||||
|
return sk;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean isStream() {
|
public boolean isStream() {
|
||||||
return checkIsStream(type);
|
return checkIsStream(type);
|
||||||
}
|
}
|
||||||
@@ -223,4 +312,20 @@ public class MultipurposeSocketAddress implements Serializable{
|
|||||||
DatagramServerSocket sk=srf.createDatagramServerSocket(port, backlog, InetAddress.getByName(host));
|
DatagramServerSocket sk=srf.createDatagramServerSocket(port, backlog, InetAddress.getByName(host));
|
||||||
return sk;
|
return sk;
|
||||||
}
|
}
|
||||||
|
public InetAddress getInetAddress() throws UnknownHostException {
|
||||||
|
return InetAddress.getByName(host);
|
||||||
|
}
|
||||||
|
public InetAddress[] getAllInetAddress() throws UnknownHostException {
|
||||||
|
return InetAddress.getAllByName(host);
|
||||||
|
}
|
||||||
|
public boolean supportNIO() {
|
||||||
|
SocketType stp= socketTypeRegister.get(getType());
|
||||||
|
if(stp==null)
|
||||||
|
return false;
|
||||||
|
if(stp.getSocketChannelFactory()==null) {
|
||||||
|
return false;
|
||||||
|
}else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,112 @@
|
|||||||
|
package org.kne.cloud.network;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.channels.ReadableByteChannel;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import org.kne.cloud.network.klalb.ByteBufferPool;
|
||||||
|
|
||||||
|
public class PacketRebuilder {
|
||||||
|
private static final ByteBufferPool bbfp=new ByteBufferPool(100, 65535);
|
||||||
|
private long timeout;
|
||||||
|
|
||||||
|
public PacketRebuilder(long timeout) {
|
||||||
|
this.timeout=timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "PacketRebuilder [timeout=" + timeout + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getTimeout() {
|
||||||
|
return timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<Integer,ReceiveEntry> recvc=new HashMap<>();
|
||||||
|
private class ReceiveEntry{
|
||||||
|
private long createTime=System.nanoTime();
|
||||||
|
private ByteBuffer[] byteBuffers;
|
||||||
|
public ReceiveEntry(ByteBuffer[] byteBuffers) {
|
||||||
|
super();
|
||||||
|
this.byteBuffers = byteBuffers;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public ByteBuffer[] getByteBuffers() {
|
||||||
|
return byteBuffers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFull() {
|
||||||
|
for (int i = 0; i < byteBuffers.length; i++) {
|
||||||
|
if(byteBuffers[i]==null)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean checkTimeout() {
|
||||||
|
return (System.nanoTime()-createTime)>timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
public void read(ByteBuffer des,ReadableByteChannel rc) throws IOException {
|
||||||
|
while(true) {
|
||||||
|
ByteBuffer cac=bbfp.borrow();
|
||||||
|
rc.read(cac);
|
||||||
|
cac.flip();
|
||||||
|
int ser=cac.getInt(0);
|
||||||
|
int countofpiece=cac.get(4);
|
||||||
|
int i=cac.get(5);
|
||||||
|
//System.out.println(cac+" "+ser+" "+countofpiece+" "+i);
|
||||||
|
if(recvc.containsKey(ser)) {
|
||||||
|
|
||||||
|
}else {
|
||||||
|
recvc.put(ser, new ReceiveEntry(new ByteBuffer[countofpiece]));
|
||||||
|
}
|
||||||
|
ReceiveEntry reet=recvc.get(ser);
|
||||||
|
reet.getByteBuffers()[i]=cac;
|
||||||
|
if(reet.isFull()) {
|
||||||
|
rebuild(des ,reet.getByteBuffers());
|
||||||
|
for (int j = 0; j < reet.getByteBuffers().length; j++) {
|
||||||
|
bbfp.back(reet.getByteBuffers()[j]);
|
||||||
|
}
|
||||||
|
recvc.remove(ser);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
for (Iterator<Entry<Integer, ReceiveEntry>> iterator = recvc.entrySet().iterator(); iterator.hasNext();) {
|
||||||
|
Entry<Integer, ReceiveEntry> type = (Entry<Integer, ReceiveEntry>) iterator.next();
|
||||||
|
ReceiveEntry rcvn=type.getValue();
|
||||||
|
if(rcvn.checkTimeout()) {
|
||||||
|
for (int j = 0; j < rcvn.getByteBuffers().length; j++) {
|
||||||
|
if(rcvn.getByteBuffers()[j]!=null)
|
||||||
|
bbfp.back(rcvn.getByteBuffers()[j]);
|
||||||
|
}
|
||||||
|
iterator.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void rebuild(ByteBuffer des, ByteBuffer[]src) {
|
||||||
|
//System.out.print("Rebuild:");
|
||||||
|
for (int i = 0; i < src.length; i++) {
|
||||||
|
src[i].getInt();
|
||||||
|
src[i].get();
|
||||||
|
src[i].get();
|
||||||
|
des.put(src[i]);
|
||||||
|
//System.out.print(src[i].limit()+" ");
|
||||||
|
}
|
||||||
|
//System.out.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
package org.kne.cloud.network;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.channels.WritableByteChannel;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import org.kne.cloud.network.klalb.ByteBufferPool;
|
||||||
|
|
||||||
|
public class PacketSpliter {
|
||||||
|
private int splitSize;
|
||||||
|
private static final ByteBufferPool bbfp=new ByteBufferPool(100,65535,false);
|
||||||
|
private AtomicInteger series=new AtomicInteger();
|
||||||
|
|
||||||
|
public PacketSpliter(int splitSize) {
|
||||||
|
this.splitSize=splitSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSplitSize() {
|
||||||
|
return splitSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "PacketSpliter [splitSize=" + splitSize + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(ByteBuffer bb,WritableByteChannel wc) throws IOException{
|
||||||
|
ByteBuffer[]bbssp= split(bb);
|
||||||
|
for (int i = 0; i < bbssp.length; i++) {
|
||||||
|
wc.write(bbssp[i]);
|
||||||
|
bbfp.back(bbssp[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteBuffer[] split(ByteBuffer bb) {
|
||||||
|
//System.out.print("Split:");
|
||||||
|
int lenth=bb.limit();
|
||||||
|
int countofpiece=(lenth-1)/splitSize+1;
|
||||||
|
int remain=lenth%splitSize;
|
||||||
|
ByteBuffer[]pieces=new ByteBuffer[countofpiece];
|
||||||
|
for (int i = 0; i < pieces.length; i++) {
|
||||||
|
pieces[i]=bbfp.borrow();
|
||||||
|
}
|
||||||
|
int sern=series.getAndIncrement();
|
||||||
|
for (int i = 0; i < pieces.length; i++) {
|
||||||
|
pieces[i].putInt(sern);
|
||||||
|
pieces[i].put((byte) countofpiece);
|
||||||
|
pieces[i].put((byte) i);
|
||||||
|
int bbl=bb.limit();
|
||||||
|
bb.limit(Math.min(bb.remaining(), pieces[i].remaining())+bb.position());
|
||||||
|
pieces[i].put(bb);
|
||||||
|
bb.limit(bbl);
|
||||||
|
//System.out.print(pieces[i].position()+" ");
|
||||||
|
pieces[i].flip();
|
||||||
|
}
|
||||||
|
//System.out.println();
|
||||||
|
return pieces;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package org.kne.cloud.network;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.ServerSocket;
|
||||||
|
import java.nio.channels.ServerSocketChannel;
|
||||||
|
import java.nio.channels.SocketChannel;
|
||||||
|
|
||||||
|
import javax.net.SocketFactory;
|
||||||
|
|
||||||
|
public abstract class ServerSocketChannelFactory {
|
||||||
|
|
||||||
|
public ServerSocketChannel createServerSocketChannel() throws IOException {
|
||||||
|
return ServerSocketChannel.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract ServerSocketChannel createServerSocketChannel(int port) throws IOException ;
|
||||||
|
|
||||||
|
public abstract ServerSocketChannel createServerSocketChannel(int port, int backlog) throws IOException ;
|
||||||
|
|
||||||
|
public abstract ServerSocketChannel createServerSocketChannel(int port, int backlog, InetAddress ifAddress) throws IOException ;
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ import java.io.InputStream;
|
|||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
|
|
||||||
|
import org.kne.cloud.network.klalb.KLALBVirtualSocket;
|
||||||
import org.kne.io.Task;
|
import org.kne.io.Task;
|
||||||
public class SocketBridge extends Task{
|
public class SocketBridge extends Task{
|
||||||
protected Socket a;
|
protected Socket a;
|
||||||
@@ -29,11 +30,17 @@ public class SocketBridge extends Task{
|
|||||||
@Override
|
@Override
|
||||||
protected void runTask() {
|
protected void runTask() {
|
||||||
try {
|
try {
|
||||||
|
if(a instanceof KLALBVirtualSocket) {
|
||||||
|
((KLALBVirtualSocket) a).associateSocket(b);
|
||||||
|
}else if(b instanceof KLALBVirtualSocket){
|
||||||
|
((KLALBVirtualSocket) b).associateSocket(a);
|
||||||
|
}else {
|
||||||
bridgeAB.runAtNewThread("SocketBridge A->B thread");
|
bridgeAB.runAtNewThread("SocketBridge A->B thread");
|
||||||
bridgeBA.runAtNewThread("SocketBridge B->A thread");
|
bridgeBA.runAtNewThread("SocketBridge B->A thread");
|
||||||
bridgeAB.waitfortask();
|
bridgeAB.waitfortask();
|
||||||
bridgeBA.waitfortask();
|
bridgeBA.waitfortask();
|
||||||
} catch (Exception e) {
|
|
||||||
|
}} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}finally {
|
}finally {
|
||||||
//new Exception().printStackTrace();
|
//new Exception().printStackTrace();
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package org.kne.cloud.network;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public abstract class SocketBridgeFactory {
|
||||||
|
public abstract SocketBridge createBridge(Socket a,Socket b) throws IOException;
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
package org.kne.cloud.network;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.net.*;
|
||||||
|
import java.nio.channels.SocketChannel;
|
||||||
|
|
||||||
|
import org.kne.cloud.network.klalb.KLALBVirtualSocket;
|
||||||
|
import org.kne.cloud.network.klalb.KLALBVirtualSocketChannel;
|
||||||
|
import org.kne.io.Task;
|
||||||
|
public class SocketChannelBridge extends Task{
|
||||||
|
protected SocketChannel a;
|
||||||
|
protected SocketChannel b;
|
||||||
|
protected StreamChannelBridge bridgeAB;
|
||||||
|
protected StreamChannelBridge bridgeBA;
|
||||||
|
public StreamChannelBridge getBridgeAB() {
|
||||||
|
return bridgeAB;
|
||||||
|
}
|
||||||
|
public StreamChannelBridge getBridgeBA() {
|
||||||
|
return bridgeBA;
|
||||||
|
}
|
||||||
|
public SocketChannelBridge(SocketChannel a, SocketChannel b) throws IOException {
|
||||||
|
super();
|
||||||
|
this.a = a;
|
||||||
|
this.b = b;
|
||||||
|
createStreamChannelBridge();
|
||||||
|
}
|
||||||
|
protected void createStreamChannelBridge() throws IOException {
|
||||||
|
bridgeAB = new StreamChannelBridge(a, b);
|
||||||
|
bridgeBA = new StreamChannelBridge(b, a);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected void runTask() {
|
||||||
|
try {
|
||||||
|
if(a instanceof KLALBVirtualSocketChannel) {
|
||||||
|
((KLALBVirtualSocketChannel) a).associateSocketChannel(b);
|
||||||
|
}else if(b instanceof KLALBVirtualSocketChannel){
|
||||||
|
((KLALBVirtualSocketChannel) b).associateSocketChannel(a);
|
||||||
|
}else {
|
||||||
|
bridgeAB.runAtNewThread("SocketBridge A->B thread");
|
||||||
|
bridgeBA.runAtNewThread("SocketBridge B->A thread");
|
||||||
|
bridgeAB.waitfortask();
|
||||||
|
bridgeBA.waitfortask();
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}finally {
|
||||||
|
//new Exception().printStackTrace();
|
||||||
|
try {
|
||||||
|
a.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
// TODO 自动生成的 catch 块
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
b.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
// TODO 自动生成的 catch 块
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public SocketChannel getA() {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
public SocketChannel getB() {
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
/*protected OutputStream getBOUT() throws IOException {
|
||||||
|
return b.getOutputStream();
|
||||||
|
}
|
||||||
|
protected InputStream getBIN() throws IOException {
|
||||||
|
return b.getInputStream();
|
||||||
|
}
|
||||||
|
protected OutputStream getAOUT() throws IOException {
|
||||||
|
return a.getOutputStream();
|
||||||
|
}
|
||||||
|
protected InputStream getAIN() throws IOException {
|
||||||
|
return a.getInputStream();
|
||||||
|
}*/
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package org.kne.cloud.network;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.nio.channels.SocketChannel;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public abstract class SocketChannelBridgeFactory {
|
||||||
|
public abstract SocketChannelBridge createBridge(SocketChannel a,SocketChannel b) throws IOException;
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package org.kne.cloud.network;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.nio.channels.SocketChannel;
|
||||||
|
|
||||||
|
import javax.net.SocketFactory;
|
||||||
|
|
||||||
|
public abstract class SocketChannelFactory {
|
||||||
|
|
||||||
|
public SocketChannel createSocketChannel() throws IOException {
|
||||||
|
return SocketChannel.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract SocketChannel createSocketChannel(String paramString, int paramInt)throws IOException, UnknownHostException ;
|
||||||
|
|
||||||
|
public abstract SocketChannel createSocketChannel(InetAddress paramInetAddress, int paramInt) throws IOException ;
|
||||||
|
|
||||||
|
public abstract SocketChannel createSocketChannel(String paramString, int paramInt1, InetAddress paramInetAddress, int paramInt2)
|
||||||
|
throws IOException, UnknownHostException ;
|
||||||
|
|
||||||
|
public abstract SocketChannel createSocketChannel(InetAddress paramInetAddress1, int paramInt1, InetAddress paramInetAddress2,
|
||||||
|
int paramInt2) throws IOException ;
|
||||||
|
}
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
package org.kne.cloud.network;
|
||||||
|
|
||||||
|
import java.io.Closeable;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.ServerSocket;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.net.SocketException;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.nio.channels.ServerSocketChannel;
|
||||||
|
import java.nio.channels.SocketChannel;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import javax.net.ServerSocketFactory;
|
||||||
|
|
||||||
|
public class SocketChannelListener implements Closeable,AutoCloseable{
|
||||||
|
protected ServerSocketChannel serverSocketChannel;
|
||||||
|
public ServerSocketChannel getServerSocketChannel() {
|
||||||
|
return serverSocketChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
private volatile boolean flag=true;
|
||||||
|
|
||||||
|
private volatile Consumer<SocketChannel>con;
|
||||||
|
private Runnable r=new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
while(flag){
|
||||||
|
try {
|
||||||
|
SocketChannel soce=serverSocketChannel.accept();
|
||||||
|
ThreadTool.makePThreadIfSupport("端口监听线程",()->{
|
||||||
|
if(con!=null) {
|
||||||
|
try {
|
||||||
|
con.accept(soce);
|
||||||
|
}catch(Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
try {
|
||||||
|
soce.close();
|
||||||
|
} catch (IOException er) {
|
||||||
|
er.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
try {
|
||||||
|
soce.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
}catch(SocketException e) {
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
private MultipurposeSocketAddress multipurposeSocketAddress;
|
||||||
|
|
||||||
|
public SocketChannelListener(MultipurposeSocketAddress multipurposeSocketAddress) throws IOException {
|
||||||
|
this.multipurposeSocketAddress=multipurposeSocketAddress;
|
||||||
|
open();
|
||||||
|
}
|
||||||
|
public SocketChannelListener(ServerSocketChannel tserverSocket) throws IOException {
|
||||||
|
this.serverSocketChannel=tserverSocket;
|
||||||
|
open();
|
||||||
|
}
|
||||||
|
protected void open() throws UnknownHostException, IOException {
|
||||||
|
if(serverSocketChannel==null)
|
||||||
|
serverSocketChannel=multipurposeSocketAddress.listenServerSocketChannel();
|
||||||
|
if(serverSocketChannel==null) {
|
||||||
|
throw new IOException(multipurposeSocketAddress.getType()+" unsupport SocketChannel");
|
||||||
|
}
|
||||||
|
new Thread(r).start();
|
||||||
|
}
|
||||||
|
public void close() {
|
||||||
|
flag=false;
|
||||||
|
if(serverSocketChannel!=null) {
|
||||||
|
try {
|
||||||
|
serverSocketChannel.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
serverSocketChannel=null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public MultipurposeSocketAddress getMultipurposeSocketAddress() {
|
||||||
|
return multipurposeSocketAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Consumer<SocketChannel> getCon() {
|
||||||
|
return con;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCon(Consumer<SocketChannel> con) {
|
||||||
|
this.con = con;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -26,7 +26,7 @@ public class SocketListener implements Closeable,AutoCloseable{
|
|||||||
while(flag){
|
while(flag){
|
||||||
try {
|
try {
|
||||||
Socket soce=serverSocket.accept();
|
Socket soce=serverSocket.accept();
|
||||||
ThreadTool.makeVThreadIfSupport("端口监听线程",()->{
|
ThreadTool.makePThreadIfSupport("端口监听线程",()->{
|
||||||
if(con!=null) {
|
if(con!=null) {
|
||||||
try {
|
try {
|
||||||
con.accept(soce);
|
con.accept(soce);
|
||||||
|
|||||||
@@ -5,13 +5,18 @@ import java.net.InetAddress;
|
|||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
|
import java.nio.channels.SocketChannel;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class SocketToSocketProxy extends Proxy {
|
public class SocketToSocketProxy extends Proxy {
|
||||||
private SocketListener sl;
|
private SocketListener sl;
|
||||||
|
private SocketChannelListener scl;
|
||||||
private DatagramSocketListener dsl;
|
private DatagramSocketListener dsl;
|
||||||
private MultipurposeSocketAddress listen, cbind, defaultConnect;
|
private MultipurposeSocketAddress listen, cbind, defaultConnect;
|
||||||
private Map<String, MultipurposeSocketAddress> detectedConnect;
|
private Map<String, MultipurposeSocketAddress> detectedConnect;
|
||||||
|
private SocketBridgeFactory defaultFactory;
|
||||||
|
private SocketChannelBridgeFactory defaultChannelFactory;
|
||||||
|
private Map<String, SocketBridgeFactory> detectedFactory;
|
||||||
|
|
||||||
public SocketToSocketProxy(MultipurposeSocketAddress listen, MultipurposeSocketAddress connect) throws IOException {
|
public SocketToSocketProxy(MultipurposeSocketAddress listen, MultipurposeSocketAddress connect) throws IOException {
|
||||||
this(listen, new MultipurposeSocketAddress(new InetSocketAddress(0)), connect);
|
this(listen, new MultipurposeSocketAddress(new InetSocketAddress(0)), connect);
|
||||||
@@ -24,10 +29,28 @@ public class SocketToSocketProxy extends Proxy {
|
|||||||
public SocketToSocketProxy(MultipurposeSocketAddress listen, MultipurposeSocketAddress cbind,
|
public SocketToSocketProxy(MultipurposeSocketAddress listen, MultipurposeSocketAddress cbind,
|
||||||
MultipurposeSocketAddress defaultConnect, Map<String, MultipurposeSocketAddress> detectedConnect)
|
MultipurposeSocketAddress defaultConnect, Map<String, MultipurposeSocketAddress> detectedConnect)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
this(listen,cbind,defaultConnect,detectedConnect,new DefaultSocketBridgeFactory(),null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SocketToSocketProxy(MultipurposeSocketAddress listen, MultipurposeSocketAddress cbind,
|
||||||
|
MultipurposeSocketAddress defaultConnect, Map<String, MultipurposeSocketAddress> detectedConnect,SocketBridgeFactory defaultFactory,Map<String, SocketBridgeFactory> detectedFactory)
|
||||||
|
throws IOException {
|
||||||
|
this(listen, cbind, defaultConnect, detectedConnect, defaultFactory, detectedFactory, new DefaultSocketChannelBridgeFactory());
|
||||||
|
}
|
||||||
|
|
||||||
|
public SocketToSocketProxy(MultipurposeSocketAddress listen, MultipurposeSocketAddress cbind,
|
||||||
|
MultipurposeSocketAddress defaultConnect, Map<String, MultipurposeSocketAddress> detectedConnect,SocketBridgeFactory defaultFactory,Map<String, SocketBridgeFactory> detectedFactory,SocketChannelBridgeFactory defaultChannelFactory)
|
||||||
|
throws IOException {
|
||||||
this.listen = listen;
|
this.listen = listen;
|
||||||
this.cbind = cbind;
|
this.cbind = cbind;
|
||||||
this.defaultConnect = defaultConnect;
|
this.defaultConnect = defaultConnect;
|
||||||
this.detectedConnect = detectedConnect;
|
this.detectedConnect = detectedConnect;
|
||||||
|
|
||||||
|
this.defaultFactory=defaultFactory;
|
||||||
|
this.detectedFactory=detectedFactory;
|
||||||
|
|
||||||
|
this.defaultChannelFactory=defaultChannelFactory;
|
||||||
|
|
||||||
open();
|
open();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,31 +61,67 @@ public class SocketToSocketProxy extends Proxy {
|
|||||||
|
|
||||||
private void open() throws IOException {
|
private void open() throws IOException {
|
||||||
if (listen.isStream()) {
|
if (listen.isStream()) {
|
||||||
if (detectedConnect == null || detectedConnect.isEmpty()) {
|
if ((detectedConnect == null || detectedConnect.isEmpty())&&(detectedFactory==null||detectedFactory.isEmpty())) {
|
||||||
|
if(listen.supportNIO()&&defaultConnect.supportNIO()&&defaultChannelFactory!=null) {
|
||||||
|
scl=new SocketChannelListener(listen);
|
||||||
|
}else {
|
||||||
sl = new SocketListener(listen);
|
sl = new SocketListener(listen);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
sl = new SocketListener(new ProtocolDetectorServerSocket(listen.listenServerSocket()));
|
sl = new SocketListener(new ProtocolDetectorServerSocket(listen.listenServerSocket()));
|
||||||
}
|
}
|
||||||
|
if(scl!=null) {
|
||||||
|
scl.setCon((socx)->{
|
||||||
|
SocketChannel sck=null;
|
||||||
|
try {
|
||||||
|
sck=defaultConnect.connectSocketChannel(InetAddress.getByName(cbind.getHost()), cbind.getPort());
|
||||||
|
runChannelBridge(defaultChannelFactory, socx, sck);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
if (sck != null)
|
||||||
|
try {
|
||||||
|
sck.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
socx.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}else {
|
||||||
sl.setCon((sox) -> {
|
sl.setCon((sox) -> {
|
||||||
Socket sk = null;
|
Socket sk = null;
|
||||||
try {
|
try {
|
||||||
if (sox instanceof ProtocolDetectorSocket) {
|
if (sox instanceof ProtocolDetectorSocket) {
|
||||||
ProtocolStack ps = ((ProtocolDetectorSocket) sox).getProtocolStack();
|
ProtocolStack ps = ((ProtocolDetectorSocket) sox).getProtocolStack();
|
||||||
if (!ps.isEmpty()) {
|
if (!ps.isEmpty()) {
|
||||||
MultipurposeSocketAddress pmsa = detectedConnect.get(ps.pop().getName());
|
String pname=ps.pop().getName();
|
||||||
|
MultipurposeSocketAddress pmsa = detectedConnect.get(pname);
|
||||||
if(pmsa!=null) {
|
if(pmsa!=null) {
|
||||||
sk = pmsa.connectSocket(InetAddress.getByName(cbind.getHost()), cbind.getPort());
|
sk = pmsa.connectSocket(InetAddress.getByName(cbind.getHost()), cbind.getPort());
|
||||||
}else {
|
}else {
|
||||||
sk = defaultConnect.connectSocket(InetAddress.getByName(cbind.getHost()), cbind.getPort());
|
sk = defaultConnect.connectSocket(InetAddress.getByName(cbind.getHost()), cbind.getPort());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
SocketBridgeFactory sbf=detectedFactory.get(pname);
|
||||||
|
if(sbf!=null) {
|
||||||
|
runBridge(sbf,sox,sk);
|
||||||
|
}else {
|
||||||
|
runBridge(defaultFactory,sox,sk);
|
||||||
|
}
|
||||||
|
runBridge(defaultFactory,sox,sk);
|
||||||
} else {
|
} else {
|
||||||
sk = defaultConnect.connectSocket(InetAddress.getByName(cbind.getHost()), cbind.getPort());
|
sk = defaultConnect.connectSocket(InetAddress.getByName(cbind.getHost()), cbind.getPort());
|
||||||
|
runBridge(defaultFactory,sox,sk);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sk = defaultConnect.connectSocket(InetAddress.getByName(cbind.getHost()), cbind.getPort());
|
sk = defaultConnect.connectSocket(InetAddress.getByName(cbind.getHost()), cbind.getPort());
|
||||||
|
runBridge(defaultFactory,sox,sk);
|
||||||
}
|
}
|
||||||
runBridge(sox,sk);
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} finally {
|
} finally {
|
||||||
@@ -79,6 +138,7 @@ public class SocketToSocketProxy extends Proxy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
dsl = new DatagramSocketListener(listen);
|
dsl = new DatagramSocketListener(listen);
|
||||||
dsl.setCon((dox) -> {
|
dsl.setCon((dox) -> {
|
||||||
@@ -87,8 +147,13 @@ public class SocketToSocketProxy extends Proxy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void runBridge(Socket sk, Socket sox) throws IOException {
|
protected void runBridge(SocketBridgeFactory sbf,Socket sk, Socket sox) throws IOException {
|
||||||
SocketBridge sb = new SocketBridge(sk, sox);
|
SocketBridge sb = sbf.createBridge(sk, sox);
|
||||||
|
sb.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void runChannelBridge(SocketChannelBridgeFactory sbf,SocketChannel sk, SocketChannel sox) throws IOException {
|
||||||
|
SocketChannelBridge sb = sbf.createBridge(sk, sox);
|
||||||
sb.run();
|
sb.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,6 +168,24 @@ public class SocketToSocketProxy extends Proxy {
|
|||||||
public MultipurposeSocketAddress getDefaultConnect() {
|
public MultipurposeSocketAddress getDefaultConnect() {
|
||||||
return defaultConnect;
|
return defaultConnect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<String, MultipurposeSocketAddress> getDetectedConnect() {
|
||||||
|
return detectedConnect;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SocketBridgeFactory getDefaultFactory() {
|
||||||
|
return defaultFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, SocketBridgeFactory> getDetectedFactory() {
|
||||||
|
return detectedFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public SocketChannelBridgeFactory getDefaultChannelFactory() {
|
||||||
|
return defaultChannelFactory;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
@@ -110,12 +193,20 @@ public class SocketToSocketProxy extends Proxy {
|
|||||||
dsl.close();
|
dsl.close();
|
||||||
if (sl != null)
|
if (sl != null)
|
||||||
sl.close();
|
sl.close();
|
||||||
|
if(scl!=null)
|
||||||
|
scl.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public InetAddress getListenAddress() {
|
public InetAddress getListenAddress() {
|
||||||
if (sl != null) {
|
if (sl != null) {
|
||||||
return sl.getServerSocket().getInetAddress();
|
return sl.getServerSocket().getInetAddress();
|
||||||
} else {
|
} else if(scl!=null){
|
||||||
|
try {
|
||||||
|
return ((InetSocketAddress)scl.getServerSocketChannel().getLocalAddress()).getAddress();
|
||||||
|
} catch (IOException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}else {
|
||||||
return dsl.getDatagramServerSocket().getLocalAddress();
|
return dsl.getDatagramServerSocket().getLocalAddress();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -123,6 +214,12 @@ public class SocketToSocketProxy extends Proxy {
|
|||||||
public int getListenPort() {
|
public int getListenPort() {
|
||||||
if (sl != null) {
|
if (sl != null) {
|
||||||
return sl.getServerSocket().getLocalPort();
|
return sl.getServerSocket().getLocalPort();
|
||||||
|
} else if(scl!=null){
|
||||||
|
try {
|
||||||
|
return ((InetSocketAddress)scl.getServerSocketChannel().getLocalAddress()).getPort();
|
||||||
|
} catch (IOException e) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return dsl.getDatagramServerSocket().getLocalPort();
|
return dsl.getDatagramServerSocket().getLocalPort();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,11 +8,15 @@ import javax.net.SocketFactory;
|
|||||||
public class SocketType {
|
public class SocketType {
|
||||||
private SocketFactory socketFactory;
|
private SocketFactory socketFactory;
|
||||||
private ServerSocketFactory serverSocketFactory;
|
private ServerSocketFactory serverSocketFactory;
|
||||||
|
|
||||||
|
private SocketChannelFactory socketChannelFactory;
|
||||||
|
private ServerSocketChannelFactory serverSocketChannelFactory;
|
||||||
|
|
||||||
private DatagramSocketFactory datagramSocketFactory;
|
private DatagramSocketFactory datagramSocketFactory;
|
||||||
private DatagramServerSocketFactory datagramServerSocketFactory;
|
private DatagramServerSocketFactory datagramServerSocketFactory;
|
||||||
private boolean stream;
|
private boolean stream;
|
||||||
|
|
||||||
public SocketFactory getSocketFactory() {
|
public SocketFactory Channel() {
|
||||||
return socketFactory;
|
return socketFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,11 +27,33 @@ public class SocketType {
|
|||||||
public DatagramSocketFactory getDatagramSocketFactory() {
|
public DatagramSocketFactory getDatagramSocketFactory() {
|
||||||
return datagramSocketFactory;
|
return datagramSocketFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public SocketChannelFactory getSocketChannelFactory() {
|
||||||
|
return socketChannelFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServerSocketChannelFactory getServerSocketChannelFactory() {
|
||||||
|
return serverSocketChannelFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SocketFactory getSocketFactory() {
|
||||||
|
return socketFactory;
|
||||||
|
}
|
||||||
|
|
||||||
public DatagramServerSocketFactory getDatagramServerSocketFactory() {
|
public DatagramServerSocketFactory getDatagramServerSocketFactory() {
|
||||||
return datagramServerSocketFactory;
|
return datagramServerSocketFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SocketType(SocketFactory socketFactory, ServerSocketFactory serverSocketFactory,
|
||||||
|
SocketChannelFactory socketChannelFactory, ServerSocketChannelFactory serverSocketChannelFactory) {
|
||||||
|
super();
|
||||||
|
this.socketFactory = socketFactory;
|
||||||
|
this.serverSocketFactory = serverSocketFactory;
|
||||||
|
this.socketChannelFactory = socketChannelFactory;
|
||||||
|
this.serverSocketChannelFactory = serverSocketChannelFactory;
|
||||||
|
this.stream=true;
|
||||||
|
}
|
||||||
|
|
||||||
public SocketType(SocketFactory socketFactory, ServerSocketFactory serverSocketFactory) {
|
public SocketType(SocketFactory socketFactory, ServerSocketFactory serverSocketFactory) {
|
||||||
super();
|
super();
|
||||||
|
|||||||
@@ -0,0 +1,82 @@
|
|||||||
|
package org.kne.cloud.network;
|
||||||
|
|
||||||
|
import java.util.concurrent.locks.LockSupport;
|
||||||
|
|
||||||
|
public class SpeedLimiter {
|
||||||
|
public boolean isHitlimit() {
|
||||||
|
return hitlimit;
|
||||||
|
}
|
||||||
|
public SpeedLimiter(long limitspeed, long timedeltans) {
|
||||||
|
super();
|
||||||
|
this.limitspeed = limitspeed;
|
||||||
|
this.timedeltans = timedeltans;
|
||||||
|
}
|
||||||
|
public SpeedLimiter() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
private volatile long limitspeed=1024*1024;
|
||||||
|
private volatile long timedeltans=5000000;
|
||||||
|
private volatile boolean hitlimit=false;
|
||||||
|
public long getLimitspeed() {
|
||||||
|
return limitspeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SpeedLimiter(long limitspeed) {
|
||||||
|
super();
|
||||||
|
this.limitspeed = limitspeed;
|
||||||
|
}
|
||||||
|
public void setLimitspeed(long limitspeed) {
|
||||||
|
this.limitspeed = limitspeed;
|
||||||
|
//System.out.println("更新限速:"+limitspeed);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getTimedeltans() {
|
||||||
|
return timedeltans;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimedeltans(long timedeltans) {
|
||||||
|
this.timedeltans = timedeltans;
|
||||||
|
}
|
||||||
|
private long ltime=System.nanoTime();
|
||||||
|
private long counter=0;
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "SpeedLimiter [limitspeed=" + limitspeed + "]";
|
||||||
|
}
|
||||||
|
public boolean checkTransmit(long datasize) {
|
||||||
|
long curtime=System.nanoTime();
|
||||||
|
if(curtime-ltime>timedeltans) {
|
||||||
|
ltime=curtime;
|
||||||
|
if((counter*1000000000)/timedeltans<=limitspeed) {
|
||||||
|
hitlimit=false;
|
||||||
|
}
|
||||||
|
counter=0;
|
||||||
|
}
|
||||||
|
if((counter*1000000000)/timedeltans<=limitspeed) {
|
||||||
|
counter+=datasize;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
hitlimit=true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
public void transmit(long datasize) {
|
||||||
|
while(true) {
|
||||||
|
long curtime=System.nanoTime();
|
||||||
|
if(curtime-ltime>timedeltans) {
|
||||||
|
ltime=curtime;
|
||||||
|
if((counter*1000000000)/timedeltans<=limitspeed) {
|
||||||
|
hitlimit=false;
|
||||||
|
}
|
||||||
|
counter=0;
|
||||||
|
}
|
||||||
|
if((counter*1000000000)/timedeltans<=limitspeed) {
|
||||||
|
counter+=datasize;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
hitlimit=true;
|
||||||
|
//System.out.println("hit limit");
|
||||||
|
LockSupport.parkNanos(100000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -30,15 +30,17 @@ public class StreamBridge extends Task{
|
|||||||
// fos.write(b, 0, v);
|
// fos.write(b, 0, v);
|
||||||
out.write(b,0,v);
|
out.write(b,0,v);
|
||||||
out.flush();
|
out.flush();
|
||||||
if(delay>0)
|
if(delay>0) {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(delay);
|
Thread.sleep(delay);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
}else {
|
||||||
|
Thread.yield();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// TODO 自动生成的 catch 块
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}finally {
|
}finally {
|
||||||
/*if(fos!=null)
|
/*if(fos!=null)
|
||||||
@@ -51,14 +53,12 @@ public class StreamBridge extends Task{
|
|||||||
if(in!=null)
|
if(in!=null)
|
||||||
in.close();
|
in.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// TODO 自动生成的 catch 块
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
if(in!=null)
|
if(in!=null)
|
||||||
out.close();
|
out.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// TODO 自动生成的 catch 块
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,90 @@
|
|||||||
|
package org.kne.cloud.network;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.channels.ReadableByteChannel;
|
||||||
|
import java.nio.channels.WritableByteChannel;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.kne.io.Task;
|
||||||
|
|
||||||
|
public class StreamChannelBridge extends Task{
|
||||||
|
protected ReadableByteChannel in;
|
||||||
|
protected WritableByteChannel out;
|
||||||
|
protected int blocksize=65535;
|
||||||
|
protected long delay=0;
|
||||||
|
public StreamChannelBridge(ReadableByteChannel in, WritableByteChannel out) {
|
||||||
|
super();
|
||||||
|
Objects.requireNonNull(in);
|
||||||
|
Objects.requireNonNull(out);
|
||||||
|
this.in = in;
|
||||||
|
this.out = out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runTask() {
|
||||||
|
//FileOutputStream fos=null;
|
||||||
|
try {
|
||||||
|
//fos=new FileOutputStream(UUID.randomUUID()+".txt");
|
||||||
|
ByteBuffer b=ByteBuffer.allocateDirect(blocksize);
|
||||||
|
while (in.read(b)!=-1) {
|
||||||
|
b.flip();
|
||||||
|
out.write(b);
|
||||||
|
b.clear();
|
||||||
|
if(delay>0) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(delay);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
Thread.yield();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}finally {
|
||||||
|
/*if(fos!=null)
|
||||||
|
try {
|
||||||
|
fos.close();
|
||||||
|
} catch (IOException e1) {
|
||||||
|
e1.printStackTrace();
|
||||||
|
}*/
|
||||||
|
try {
|
||||||
|
if(in!=null)
|
||||||
|
in.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if(in!=null)
|
||||||
|
out.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public int getBlocksize() {
|
||||||
|
return blocksize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBlocksize(int blocksize) {
|
||||||
|
this.blocksize = blocksize;
|
||||||
|
}
|
||||||
|
public long getDelay() {
|
||||||
|
return delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDelay(long delay) {
|
||||||
|
this.delay = delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void runAtNewThread() {
|
||||||
|
runAtNewThread("StreamBridge thread");
|
||||||
|
}
|
||||||
|
public void runAtNewThread(String name) {
|
||||||
|
ThreadTool.makeVThreadIfSupport(name, this).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package org.kne.cloud.network;
|
||||||
|
|
||||||
|
import java.io.Closeable;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Timer;
|
||||||
|
import java.util.TimerTask;
|
||||||
|
|
||||||
|
public class TimeoutTimer extends Timer {
|
||||||
|
public TimeoutTimer() {
|
||||||
|
super( "接收超时计时器线程", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimerTask createTimeOutTask(Closeable res,long timeout) {
|
||||||
|
TimerTask tt;
|
||||||
|
if(timeout>0) {
|
||||||
|
tt=new TimerTask() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
res.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}else {
|
||||||
|
tt=null;
|
||||||
|
}
|
||||||
|
schedule(tt, timeout);
|
||||||
|
return tt;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -48,7 +48,7 @@ public abstract class VirtualServerSocket extends ServerSocket {
|
|||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
public VirtualSocketImpl getVirtualImpl() {
|
protected VirtualSocketImpl getVirtualImpl() {
|
||||||
return virtualImpl;
|
return virtualImpl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ public abstract class VirtualSocket extends Socket {
|
|||||||
|
|
||||||
private VirtualSocketImpl virtualImpl;
|
private VirtualSocketImpl virtualImpl;
|
||||||
|
|
||||||
public VirtualSocketImpl getVirtualImpl() {
|
protected VirtualSocketImpl getVirtualImpl() {
|
||||||
return virtualImpl;
|
return virtualImpl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,31 +19,26 @@ public class FrpcIni extends Ini {
|
|||||||
|
|
||||||
public FrpcIni(File input) throws IOException, InvalidFileFormatException {
|
public FrpcIni(File input) throws IOException, InvalidFileFormatException {
|
||||||
super(input);
|
super(input);
|
||||||
// TODO 自动生成的构造函数存根
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public FrpcIni(InputStream input) throws IOException, InvalidFileFormatException {
|
public FrpcIni(InputStream input) throws IOException, InvalidFileFormatException {
|
||||||
super(input);
|
super(input);
|
||||||
// TODO 自动生成的构造函数存根
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public FrpcIni(Reader input) throws IOException, InvalidFileFormatException {
|
public FrpcIni(Reader input) throws IOException, InvalidFileFormatException {
|
||||||
super(input);
|
super(input);
|
||||||
// TODO 自动生成的构造函数存根
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public FrpcIni(URL input) throws IOException, InvalidFileFormatException {
|
public FrpcIni(URL input) throws IOException, InvalidFileFormatException {
|
||||||
super(input);
|
super(input);
|
||||||
// TODO 自动生成的构造函数存根
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public FrpcIni(String str) throws InvalidFileFormatException {
|
public FrpcIni(String str) throws IOException ,InvalidFileFormatException{
|
||||||
this();
|
super(new StringReader(str));
|
||||||
loadFromString(str);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setServerAddr(String addr) {
|
public void setServerAddr(String addr) {
|
||||||
add("common", "server_addr", addr);
|
put("common", "server_addr", addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getServerAddr() {
|
public String getServerAddr() {
|
||||||
@@ -51,7 +46,7 @@ public class FrpcIni extends Ini {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setToken(String addr) {
|
public void setToken(String addr) {
|
||||||
add("common", "token", addr);
|
put("common", "token", addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getToken() {
|
public String getToken() {
|
||||||
@@ -59,7 +54,7 @@ public class FrpcIni extends Ini {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setProtocol(String protocol) {
|
public void setProtocol(String protocol) {
|
||||||
add("common", "protocol", protocol);
|
put("common", "protocol", protocol);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getProtocol() {
|
public String getProtocol() {
|
||||||
@@ -67,7 +62,7 @@ public class FrpcIni extends Ini {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setServerPort(int port) {
|
public void setServerPort(int port) {
|
||||||
add("common", "server_port", port);
|
put("common", "server_port", port);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getServerPort() {
|
public int getServerPort() {
|
||||||
@@ -75,14 +70,14 @@ public class FrpcIni extends Ini {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setDnsServer(String dns) {
|
public void setDnsServer(String dns) {
|
||||||
add("common", "dns_server", dns);
|
put("common", "dns_server", dns);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDnsServer() {
|
public String getDnsServer() {
|
||||||
return get("common", "dns_server");
|
return get("common", "dns_server");
|
||||||
}
|
}
|
||||||
public void setConnectServerLocalIp(String connectserverlocalip) {
|
public void setConnectServerLocalIp(String connectserverlocalip) {
|
||||||
add("common", "connect_server_local_ip", connectserverlocalip);
|
put("common", "connect_server_local_ip", connectserverlocalip);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getConnectServerLocalIp() {
|
public String getConnectServerLocalIp() {
|
||||||
@@ -90,7 +85,7 @@ public class FrpcIni extends Ini {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setUser(String user) {
|
public void setUser(String user) {
|
||||||
add("common", "user", user);
|
put("common", "user", user);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUser() {
|
public String getUser() {
|
||||||
@@ -98,7 +93,7 @@ public class FrpcIni extends Ini {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setTcpMux(boolean tcpmux) {
|
public void setTcpMux(boolean tcpmux) {
|
||||||
add("common", "tcp_mux", tcpmux);
|
put("common", "tcp_mux", tcpmux);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getTcpMux() {
|
public boolean getTcpMux() {
|
||||||
@@ -106,7 +101,7 @@ public class FrpcIni extends Ini {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setTlsEnable(boolean tlsenable) {
|
public void setTlsEnable(boolean tlsenable) {
|
||||||
add("common", "tls_enable", tlsenable);
|
put("common", "tls_enable", tlsenable);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getTlsEnable() {
|
public boolean getTlsEnable() {
|
||||||
@@ -125,63 +120,63 @@ public class FrpcIni extends Ini {
|
|||||||
|
|
||||||
|
|
||||||
public void setType(String tunnel,String type) {
|
public void setType(String tunnel,String type) {
|
||||||
add(tunnel, "type", type);
|
put(tunnel, "type", type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getType(String tunnel) {
|
public String getType(String tunnel) {
|
||||||
return get(tunnel, "type");
|
return get(tunnel, "type");
|
||||||
}
|
}
|
||||||
public void setLocalIP (String tunnel,String localip) {
|
public void setLocalIP (String tunnel,String localip) {
|
||||||
add(tunnel, "local_ip", localip);
|
put(tunnel, "local_ip", localip);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getLocalIP(String tunnel) {
|
public String getLocalIP(String tunnel) {
|
||||||
return get(tunnel, "local_ip");
|
return get(tunnel, "local_ip");
|
||||||
}
|
}
|
||||||
public void setLocalPort (String tunnel,int localport) {
|
public void setLocalPort (String tunnel,int localport) {
|
||||||
add(tunnel, "local_port", localport);
|
put(tunnel, "local_port", localport);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getLocalPort(String tunnel) {
|
public int getLocalPort(String tunnel) {
|
||||||
return get(tunnel, "local_port",int.class);
|
return get(tunnel, "local_port",int.class);
|
||||||
}
|
}
|
||||||
public void setRemotePort (String tunnel,int remoteport) {
|
public void setRemotePort (String tunnel,int remoteport) {
|
||||||
add(tunnel, "remote_port", remoteport);
|
put(tunnel, "remote_port", remoteport);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getRemotePort(String tunnel) {
|
public int getRemotePort(String tunnel) {
|
||||||
return get(tunnel, "remote_port",int.class);
|
return get(tunnel, "remote_port",int.class);
|
||||||
}
|
}
|
||||||
public void setUseEncryption (String tunnel,boolean useencryption) {
|
public void setUseEncryption (String tunnel,boolean useencryption) {
|
||||||
add(tunnel, "use_encryption", useencryption);
|
put(tunnel, "use_encryption", useencryption);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getUseEncryption(String tunnel) {
|
public boolean getUseEncryption(String tunnel) {
|
||||||
return get(tunnel, "use_encryption",boolean.class);
|
return get(tunnel, "use_encryption",boolean.class);
|
||||||
}
|
}
|
||||||
public void setUseCompression (String tunnel,boolean usecompression) {
|
public void setUseCompression (String tunnel,boolean usecompression) {
|
||||||
add(tunnel, "use_compression", usecompression);
|
put(tunnel, "use_compression", usecompression);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getUseCompression(String tunnel) {
|
public boolean getUseCompression(String tunnel) {
|
||||||
return get(tunnel, "use_compression",boolean.class);
|
return get(tunnel, "use_compression",boolean.class);
|
||||||
}
|
}
|
||||||
public void setSk(String tunnel,String sk) {
|
public void setSk(String tunnel,String sk) {
|
||||||
add(tunnel, "sk", sk);
|
put(tunnel, "sk", sk);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSk(String tunnel) {
|
public String getSk(String tunnel) {
|
||||||
return get(tunnel, "sk");
|
return get(tunnel, "sk");
|
||||||
}
|
}
|
||||||
public void setRole(String tunnel,String sk) {
|
public void setRole(String tunnel,String sk) {
|
||||||
add(tunnel, "role", sk);
|
put(tunnel, "role", sk);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRole(String tunnel) {
|
public String getRole(String tunnel) {
|
||||||
return get(tunnel, "role");
|
return get(tunnel, "role");
|
||||||
}
|
}
|
||||||
public void setServerName(String tunnel,String servername) {
|
public void setServerName(String tunnel,String servername) {
|
||||||
add(tunnel, "server_name", servername);
|
put(tunnel, "server_name", servername);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getServerName(String tunnel) {
|
public String getServerName(String tunnel) {
|
||||||
@@ -189,21 +184,21 @@ public class FrpcIni extends Ini {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setBindAddr(String tunnel,String bindaddr) {
|
public void setBindAddr(String tunnel,String bindaddr) {
|
||||||
add(tunnel, "bind_addr", bindaddr);
|
put(tunnel, "bind_addr", bindaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getBindAddr(String tunnel) {
|
public String getBindAddr(String tunnel) {
|
||||||
return get(tunnel, "bind_addr");
|
return get(tunnel, "bind_addr");
|
||||||
}
|
}
|
||||||
public void setBindPort (String tunnel,int bindport) {
|
public void setBindPort (String tunnel,int bindport) {
|
||||||
add(tunnel, "bind_port", bindport);
|
put(tunnel, "bind_port", bindport);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getBindPort(String tunnel) {
|
public int getBindPort(String tunnel) {
|
||||||
return get(tunnel, "bind_port",int.class);
|
return get(tunnel, "bind_port",int.class);
|
||||||
}
|
}
|
||||||
public void setKeepTunnelOpen (String tunnel,boolean keeptunnelopen) {
|
public void setKeepTunnelOpen (String tunnel,boolean keeptunnelopen) {
|
||||||
add(tunnel, "keep_tunnel_open", keeptunnelopen);
|
put(tunnel, "keep_tunnel_open", keeptunnelopen);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getKeepTunnelOpen(String tunnel) {
|
public boolean getKeepTunnelOpen(String tunnel) {
|
||||||
@@ -215,6 +210,7 @@ public class FrpcIni extends Ini {
|
|||||||
StringWriter sw = new StringWriter();
|
StringWriter sw = new StringWriter();
|
||||||
try {
|
try {
|
||||||
store(sw);
|
store(sw);
|
||||||
|
//System.out.println(sw);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ public class FrpcProcess extends Process{
|
|||||||
private File base;
|
private File base;
|
||||||
private File exe;
|
private File exe;
|
||||||
private Process theProcess;
|
private Process theProcess;
|
||||||
|
|
||||||
|
private File config_file;
|
||||||
|
|
||||||
public FrpcProcess(String ini) throws IOException {
|
public FrpcProcess(String ini) throws IOException {
|
||||||
this(defaultBase,ini);
|
this(defaultBase,ini);
|
||||||
@@ -50,11 +52,14 @@ public class FrpcProcess extends Process{
|
|||||||
}else {
|
}else {
|
||||||
exe=new File(base,"frpc_linux_amd64");
|
exe=new File(base,"frpc_linux_amd64");
|
||||||
}
|
}
|
||||||
File f=new File(base,"frpc_conf.ini");
|
AtomicReference<IOException >arex=new AtomicReference<IOException >();
|
||||||
f.createNewFile();
|
synchronized (getClass()) {
|
||||||
|
config_file = new File(base,"frpc_conf_"+UUID.randomUUID()+".ini");
|
||||||
|
config_file.createNewFile();
|
||||||
|
config_file.deleteOnExit();
|
||||||
PrintWriter ps=null;
|
PrintWriter ps=null;
|
||||||
try {
|
try {
|
||||||
ps=new PrintWriter(f);
|
ps=new PrintWriter(config_file);
|
||||||
ps.println(ini);
|
ps.println(ini);
|
||||||
}finally {
|
}finally {
|
||||||
if(ps!=null)
|
if(ps!=null)
|
||||||
@@ -63,12 +68,23 @@ public class FrpcProcess extends Process{
|
|||||||
List<String>lstc=new ArrayList<>();
|
List<String>lstc=new ArrayList<>();
|
||||||
lstc.add(exe.getAbsolutePath());
|
lstc.add(exe.getAbsolutePath());
|
||||||
lstc.add("-c");
|
lstc.add("-c");
|
||||||
lstc.add(f.getName());
|
lstc.add(config_file.getName());
|
||||||
ProcessBuilder psb=new ProcessBuilder(lstc);
|
ProcessBuilder psb=new ProcessBuilder(lstc);
|
||||||
psb.directory(base);
|
psb.directory(base);
|
||||||
theProcess=psb.start();
|
theProcess=psb.start();
|
||||||
AtomicReference<IOException >arex=new AtomicReference<IOException >();
|
|
||||||
Thread t=Thread.currentThread();
|
Thread t=Thread.currentThread();
|
||||||
|
|
||||||
|
hook=new Thread(()->{
|
||||||
|
try {
|
||||||
|
hook=null;
|
||||||
|
finalize();
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Runtime.getRuntime().addShutdownHook(hook);
|
||||||
|
|
||||||
|
CountDownLatch cdl=new CountDownLatch(1);
|
||||||
new Thread(()->{
|
new Thread(()->{
|
||||||
BufferedReader br=new BufferedReader(new InputStreamReader(theProcess.getInputStream()));
|
BufferedReader br=new BufferedReader(new InputStreamReader(theProcess.getInputStream()));
|
||||||
|
|
||||||
@@ -78,6 +94,7 @@ public class FrpcProcess extends Process{
|
|||||||
if(s==null) {
|
if(s==null) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
cdl.countDown();
|
||||||
System.out.println (s);
|
System.out.println (s);
|
||||||
if(s.contains("start proxy success")) {
|
if(s.contains("start proxy success")) {
|
||||||
t.interrupt();
|
t.interrupt();
|
||||||
@@ -93,6 +110,9 @@ public class FrpcProcess extends Process{
|
|||||||
}else if(s.contains("already exists")&&s.contains("proxy")) {
|
}else if(s.contains("already exists")&&s.contains("proxy")) {
|
||||||
arex.set(new BindException("proxy already exists"));
|
arex.set(new BindException("proxy already exists"));
|
||||||
t.interrupt();
|
t.interrupt();
|
||||||
|
}else if(s.contains("已经存在, 请检查是否重复开启")&&s.contains("隧道")) {
|
||||||
|
arex.set(new BindException("proxy already exists"));
|
||||||
|
t.interrupt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@@ -106,6 +126,13 @@ public class FrpcProcess extends Process{
|
|||||||
}
|
}
|
||||||
|
|
||||||
}).start();
|
}).start();
|
||||||
|
try {
|
||||||
|
cdl.await(5000, TimeUnit.MILLISECONDS);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if(theProcess.waitFor(20000, TimeUnit.MILLISECONDS)) {
|
if(theProcess.waitFor(20000, TimeUnit.MILLISECONDS)) {
|
||||||
destroy();
|
destroy();
|
||||||
@@ -115,23 +142,17 @@ public class FrpcProcess extends Process{
|
|||||||
throw new SocketException("Frpc timed out");
|
throw new SocketException("Frpc timed out");
|
||||||
}
|
}
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
|
//destroy();
|
||||||
|
Thread.interrupted();
|
||||||
if(arex.get()!=null) {
|
if(arex.get()!=null) {
|
||||||
destroy();
|
destroy();
|
||||||
arex.get().fillInStackTrace();
|
arex.get().fillInStackTrace();
|
||||||
throw arex.get();
|
throw arex.get();
|
||||||
}
|
}
|
||||||
}finally {
|
|
||||||
Thread.interrupted();
|
|
||||||
}
|
}
|
||||||
hook=new Thread(()->{
|
|
||||||
try {
|
|
||||||
hook=null;
|
|
||||||
finalize();
|
|
||||||
} catch (Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Runtime.getRuntime().addShutdownHook(hook);
|
|
||||||
}
|
}
|
||||||
public File getBase() {
|
public File getBase() {
|
||||||
return base;
|
return base;
|
||||||
@@ -163,6 +184,9 @@ public class FrpcProcess extends Process{
|
|||||||
if(hook!=null) {
|
if(hook!=null) {
|
||||||
Runtime.getRuntime().removeShutdownHook(hook);
|
Runtime.getRuntime().removeShutdownHook(hook);
|
||||||
}
|
}
|
||||||
|
if(config_file!=null) {
|
||||||
|
config_file.delete();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public boolean waitFor(long timeout, TimeUnit unit) throws InterruptedException {
|
public boolean waitFor(long timeout, TimeUnit unit) throws InterruptedException {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import java.net.SocketImpl;
|
|||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.ini4j.Profile.Section;
|
import org.ini4j.Profile.Section;
|
||||||
import org.kne.cloud.network.MultipurposeSocketAddress;
|
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||||
@@ -85,7 +86,7 @@ public class FrpcServerSocket extends ServerSocket {
|
|||||||
public void bind(SocketAddress endpoint, int backlog) throws IOException {
|
public void bind(SocketAddress endpoint, int backlog) throws IOException {
|
||||||
if(frpcini!=null) {
|
if(frpcini!=null) {
|
||||||
if(tunnel==null) {
|
if(tunnel==null) {
|
||||||
var e=frpcini.keySet();
|
Set<String> e=frpcini.keySet();
|
||||||
for (Iterator<String> iterator = e.iterator(); iterator.hasNext();) {
|
for (Iterator<String> iterator = e.iterator(); iterator.hasNext();) {
|
||||||
String key = iterator.next();
|
String key = iterator.next();
|
||||||
if(!key.equals("common")) {
|
if(!key.equals("common")) {
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package org.kne.cloud.network.frpc;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import org.ini4j.InvalidFileFormatException;
|
||||||
|
|
||||||
|
import com.moandjiezana.toml.Toml;
|
||||||
|
import com.moandjiezana.toml.TomlWriter;
|
||||||
|
public class FrpcToml extends Toml{
|
||||||
|
|
||||||
|
public FrpcToml() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
public FrpcToml(File input) throws IOException, InvalidFileFormatException {
|
||||||
|
Toml t=new Toml().read(input);
|
||||||
|
System.out.println(t.toMap());
|
||||||
|
}
|
||||||
|
|
||||||
|
public FrpcToml(InputStream input) throws IOException, InvalidFileFormatException {
|
||||||
|
Toml t=new Toml().read(input);
|
||||||
|
System.out.println(t.toMap());
|
||||||
|
}
|
||||||
|
|
||||||
|
public FrpcToml(Reader input) throws IOException, InvalidFileFormatException {
|
||||||
|
Toml t=new Toml().read(input);
|
||||||
|
System.out.println(t.toMap());
|
||||||
|
}
|
||||||
|
|
||||||
|
public FrpcToml(String input) throws InvalidFileFormatException {
|
||||||
|
Toml t=new Toml().read(input);
|
||||||
|
System.out.println(t.toMap());
|
||||||
|
}
|
||||||
|
public static void main(String[] args) throws IOException {
|
||||||
|
Toml t=new Toml().read(new File("C:\\KNE的文件夹\\coding\\java\\KLALB\\frpc\\frpc.toml"));
|
||||||
|
System.out.println(t.toMap());
|
||||||
|
TomlWriter te=new TomlWriter();
|
||||||
|
System.out.println( te.write(""));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,114 +5,57 @@ import java.io.DataInputStream;
|
|||||||
import java.io.DataOutput;
|
import java.io.DataOutput;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.channels.Channel;
|
||||||
|
import java.nio.channels.Channels;
|
||||||
|
import java.nio.channels.ReadableByteChannel;
|
||||||
|
import java.nio.channels.WritableByteChannel;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
public class ACKTPacket extends KLALBPacket implements PortPacket {
|
public class ACKTPacket extends KLALBPacket implements PortPacket {
|
||||||
private int sport,dport;
|
|
||||||
private long number;
|
|
||||||
private boolean avaliable;
|
|
||||||
private int sendcount;
|
|
||||||
|
|
||||||
public ACKTPacket(int sport,int dport,long number,boolean avaliable,int sendcount) {
|
public ACKTPacket(int sport,int dport,long number,boolean avaliable,int sendcount) {
|
||||||
super(ACKT);
|
super(ACKT);
|
||||||
this.sport=sport;
|
header.putInt(sport);
|
||||||
this.dport=dport;
|
header.putInt(dport);
|
||||||
this.number=number;
|
header.putLong(number);
|
||||||
this.avaliable=avaliable;
|
header.put((byte) sendcount);
|
||||||
this.sendcount=sendcount;
|
header.put((byte) (avaliable?1:0));
|
||||||
}
|
}
|
||||||
|
|
||||||
public ACKTPacket() {
|
public ACKTPacket(ByteBuffer bb) {
|
||||||
super(ACKT);
|
super(bb);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "ACKT "+sport+"->"+dport+" "+number+"[] "+avaliable;
|
return "ACKT "+getSport()+"->"+getDport()+" "+getNumber()+"[] "+isAvaliable();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSport() {
|
public int getSport() {
|
||||||
return sport;
|
return header.getInt(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getLength() {
|
public int getHeaderSize() {
|
||||||
return super.getLength()+18;
|
return super.getHeaderSize()+18;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getDport() {
|
public int getDport() {
|
||||||
return dport;
|
return header.getInt(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getNumber() {
|
public long getNumber() {
|
||||||
return number;
|
return header.getLong(9);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isAvaliable() {
|
public boolean isAvaliable() {
|
||||||
return avaliable;
|
return header.get(18)!=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public int getSendcount() {
|
public int getSendcount() {
|
||||||
return sendcount;
|
return header.getInt(17);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final byte[] writeBuffer = new byte[18];
|
|
||||||
@Override
|
|
||||||
protected void writeToStream(DataOutput dto) throws IOException {
|
|
||||||
super.writeToStream(dto);
|
|
||||||
/*dto.writeInt(sport);
|
|
||||||
dto.writeInt(dport);
|
|
||||||
dto.writeLong(number);
|
|
||||||
dto.writeByte(sendcount);
|
|
||||||
dto.writeBoolean(avaliable);*/
|
|
||||||
writeBuffer[0] = (byte)(sport >>> 24);
|
|
||||||
writeBuffer[1] = (byte)(sport >>> 16);
|
|
||||||
writeBuffer[2] = (byte)(sport >>> 8);
|
|
||||||
writeBuffer[3] = (byte)(sport >>> 0);
|
|
||||||
|
|
||||||
writeBuffer[4] = (byte)(dport >>> 24);
|
|
||||||
writeBuffer[5] = (byte)(dport >>> 16);
|
|
||||||
writeBuffer[6] = (byte)(dport >>> 8);
|
|
||||||
writeBuffer[7] = (byte)(dport >>> 0);
|
|
||||||
|
|
||||||
writeBuffer[8] = (byte)(number >>> 56);
|
|
||||||
writeBuffer[9] = (byte)(number >>> 48);
|
|
||||||
writeBuffer[10] = (byte)(number >>> 40);
|
|
||||||
writeBuffer[11] = (byte)(number >>> 32);
|
|
||||||
writeBuffer[12] = (byte)(number >>> 24);
|
|
||||||
writeBuffer[13] = (byte)(number >>> 16);
|
|
||||||
writeBuffer[14] = (byte)(number >>> 8);
|
|
||||||
writeBuffer[15] = (byte)(number >>> 0);
|
|
||||||
|
|
||||||
writeBuffer[16]=(byte) getSendRecord().size();
|
|
||||||
|
|
||||||
writeBuffer[17]=(byte) (avaliable ? 1 : 0);
|
|
||||||
dto.write(writeBuffer);
|
|
||||||
}
|
|
||||||
private final byte[] readBuffer = new byte[18];
|
|
||||||
@Override
|
|
||||||
protected void readFromStream(DataInput din) throws IOException {
|
|
||||||
super.readFromStream(din);
|
|
||||||
/*sport=din.readInt();
|
|
||||||
dport=din.readInt();
|
|
||||||
number=din.readLong();
|
|
||||||
sendcount=din.readUnsignedByte();
|
|
||||||
avaliable=din.readBoolean();*/
|
|
||||||
|
|
||||||
din.readFully(readBuffer);
|
|
||||||
sport=((readBuffer[0] << 24) + (readBuffer[1] << 16) + (readBuffer[2] << 8) + (readBuffer[3] << 0));
|
|
||||||
dport=((readBuffer[4] << 24) + (readBuffer[5] << 16) + (readBuffer[6] << 8) + (readBuffer[7] << 0));
|
|
||||||
number=(((long)readBuffer[8] << 56) +
|
|
||||||
((long)(readBuffer[9] & 255) << 48) +
|
|
||||||
((long)(readBuffer[10] & 255) << 40) +
|
|
||||||
((long)(readBuffer[11] & 255) << 32) +
|
|
||||||
((long)(readBuffer[12] & 255) << 24) +
|
|
||||||
((readBuffer[13] & 255) << 16) +
|
|
||||||
((readBuffer[14] & 255) << 8) +
|
|
||||||
((readBuffer[15] & 255) << 0));
|
|
||||||
sendcount=readBuffer[16]&0xff;
|
|
||||||
avaliable=(readBuffer[17] != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,17 @@
|
|||||||
package org.kne.cloud.network.klalb;
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
import java.io.DataInput;
|
import java.io.DataInput;
|
||||||
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutput;
|
import java.io.DataOutput;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.EOFException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.Inet6Address;
|
import java.net.Inet6Address;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.channels.Channels;
|
||||||
|
import java.nio.channels.ReadableByteChannel;
|
||||||
|
import java.nio.channels.WritableByteChannel;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
public class ADDLINESPacket extends KLALBPacket {
|
public class ADDLINESPacket extends KLALBPacket {
|
||||||
private String lines;
|
private String lines;
|
||||||
@@ -18,43 +26,49 @@ public class ADDLINESPacket extends KLALBPacket {
|
|||||||
this.lines=lines;
|
this.lines=lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ADDLINESPacket() {
|
|
||||||
super(ADDLINES);
|
public ADDLINESPacket(ByteBuffer bb) {
|
||||||
}
|
super(bb);
|
||||||
private int UTFlength(String str) {
|
|
||||||
int strlen = str.length();
|
|
||||||
int utflen = 0;
|
|
||||||
for (int i = 0; i < strlen; i++) {
|
|
||||||
int c = str.charAt(i);
|
|
||||||
if ((c >= 0x0001) && (c <= 0x007F)) {
|
|
||||||
utflen++;
|
|
||||||
} else if (c > 0x07FF) {
|
|
||||||
utflen += 3;
|
|
||||||
} else {
|
|
||||||
utflen += 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return utflen;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "ADDLINES\n"+lines;
|
return "ADDLINES "+getLines();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||||
|
byte[]bta=lines.getBytes(Charset.forName("UTF-8"));
|
||||||
|
header.putChar(1,(char) bta.length);
|
||||||
|
super.writeToChannel(dto);
|
||||||
|
dto.write(ByteBuffer.wrap(bta));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void readFromChannel(ReadableByteChannel din) throws IOException {
|
||||||
|
super.readFromChannel(din);
|
||||||
|
int lth=header.getChar(1);
|
||||||
|
byte[]b=new byte[lth];
|
||||||
|
ByteBuffer wp= ByteBuffer.wrap(b);
|
||||||
|
while(wp.hasRemaining()){
|
||||||
|
if(din.read(wp)==-1) {
|
||||||
|
throw new EOFException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lines=new String(b, Charset.forName("UTF-8"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getHeaderSize() {
|
||||||
|
return super.getHeaderSize()+2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getLength() {
|
public long getLength() {
|
||||||
return super.getLength()+2+UTFlength(lines);
|
return super.getLength()+2+lines.getBytes(Charset.forName("UTF-8")).length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void writeToStream(DataOutput dto) throws IOException {
|
|
||||||
super.writeToStream(dto);
|
|
||||||
dto.writeUTF(lines);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void readFromStream(DataInput din) throws IOException {
|
|
||||||
super.readFromStream(din);
|
|
||||||
lines=din.readUTF();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
|
import java.io.DataInput;
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutput;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
public class BWINFPacket extends KLALBPacket {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public long getUpSpeed() {
|
||||||
|
return header.getLong(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getDownSpeed() {
|
||||||
|
return header.getLong(9);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getLength() {
|
||||||
|
return super.getLength()+16;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getHeaderSize() {
|
||||||
|
return super.getHeaderSize()+16;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BWINFPacket(long upSpeed,long downSpeed) {
|
||||||
|
super( BWINF,-1);
|
||||||
|
header.putLong(upSpeed);
|
||||||
|
header.putLong(downSpeed);
|
||||||
|
}
|
||||||
|
public BWINFPacket(ByteBuffer bb) {
|
||||||
|
super(bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return " BWINF";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
|
import java.util.concurrent.ArrayBlockingQueue;
|
||||||
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
|
|
||||||
|
public class ByteArrayPool {
|
||||||
|
private ArrayBlockingQueue<byte[]>rec;
|
||||||
|
private int maxcount;
|
||||||
|
private int length;
|
||||||
|
public ByteArrayPool(int maxcount, int length) {
|
||||||
|
super();
|
||||||
|
this.maxcount = maxcount;
|
||||||
|
this.length = length;
|
||||||
|
rec=new ArrayBlockingQueue<byte[]>(length);
|
||||||
|
}
|
||||||
|
public void back(byte[]b) {
|
||||||
|
if(b.length!=length)
|
||||||
|
throw new IllegalArgumentException("wrong length");
|
||||||
|
rec.offer(b);
|
||||||
|
}
|
||||||
|
public byte[] borrow() {
|
||||||
|
byte[]b=rec.poll();
|
||||||
|
if(b==null) {
|
||||||
|
b=new byte[length];
|
||||||
|
}
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
public int getMaxCount() {
|
||||||
|
return maxcount;
|
||||||
|
}
|
||||||
|
public int getLength() {
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
package org.kne.cloud.network.klalb;
|
|
||||||
|
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
|
||||||
|
|
||||||
public class ByteArrayRecycle {
|
|
||||||
private ConcurrentLinkedQueue<byte[]>rec=new ConcurrentLinkedQueue<>();
|
|
||||||
private int capacity;
|
|
||||||
private int length;
|
|
||||||
public ByteArrayRecycle(int capacity, int length) {
|
|
||||||
super();
|
|
||||||
this.capacity = capacity;
|
|
||||||
this.length = length;
|
|
||||||
}
|
|
||||||
public void recycle(byte[]b) {
|
|
||||||
if(b.length!=length)
|
|
||||||
throw new IllegalArgumentException("wrong length");
|
|
||||||
if(rec.size()<capacity) {
|
|
||||||
rec.add(b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public byte[] create() {
|
|
||||||
byte[]b=rec.poll();
|
|
||||||
if(b==null) {
|
|
||||||
b=new byte[length];
|
|
||||||
}
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.concurrent.ArrayBlockingQueue;
|
||||||
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
|
|
||||||
|
public class ByteBufferPool {
|
||||||
|
private ArrayBlockingQueue<ByteBuffer>rec;
|
||||||
|
private int maxcount;
|
||||||
|
private int length;
|
||||||
|
private boolean direct;
|
||||||
|
public ByteBufferPool(int maxcount, int length,boolean direct) {
|
||||||
|
super();
|
||||||
|
this.maxcount = maxcount;
|
||||||
|
this.length = length;
|
||||||
|
this.direct=direct;
|
||||||
|
rec=new ArrayBlockingQueue<ByteBuffer>(length);
|
||||||
|
}
|
||||||
|
public ByteBufferPool(int maxcount, int length) {
|
||||||
|
this(maxcount, length, true);
|
||||||
|
}
|
||||||
|
public void back(ByteBuffer b) {
|
||||||
|
if(b.capacity()!=length)
|
||||||
|
throw new IllegalArgumentException("wrong length");
|
||||||
|
b.clear();
|
||||||
|
rec.offer(b);
|
||||||
|
}
|
||||||
|
public ByteBuffer borrow() {
|
||||||
|
ByteBuffer b=rec.poll();
|
||||||
|
if(b==null) {
|
||||||
|
if(direct)
|
||||||
|
b=ByteBuffer.allocateDirect(length);
|
||||||
|
else
|
||||||
|
b=ByteBuffer.allocate(length);
|
||||||
|
}
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
public int getMaxCount() {
|
||||||
|
return maxcount;
|
||||||
|
}
|
||||||
|
public int getLength() {
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -2,5 +2,5 @@ package org.kne.cloud.network.klalb;
|
|||||||
|
|
||||||
public class CONST {
|
public class CONST {
|
||||||
public static String klalb="KLALB";
|
public static String klalb="KLALB";
|
||||||
public static String klalbver="2.2";
|
public static String klalbver="2.3";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,168 +1,140 @@
|
|||||||
package org.kne.cloud.network.klalb;
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
import java.io.DataInput;
|
import java.io.DataInput;
|
||||||
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutput;
|
import java.io.DataOutput;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.EOFException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.StreamCorruptedException;
|
import java.io.StreamCorruptedException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.channels.Channels;
|
||||||
|
import java.nio.channels.ReadableByteChannel;
|
||||||
|
import java.nio.channels.WritableByteChannel;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.zip.CRC32;
|
import java.util.zip.CRC32;
|
||||||
|
|
||||||
import javax.sound.sampled.Port;
|
import javax.sound.sampled.Port;
|
||||||
|
|
||||||
public class DATATPacket extends KLALBPacket implements Comparable<DATATPacket>,PortPacket{
|
public class DATATPacket extends KLALBPacket implements PortPacket{
|
||||||
public static final ByteArrayRecycle arrayRecycle=new ByteArrayRecycle(5000,65535);
|
/*private int sport,dport;
|
||||||
@Override
|
|
||||||
public long getLength() {
|
|
||||||
return super.getLength()+19+size;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int sport,dport;
|
|
||||||
private long number;
|
private long number;
|
||||||
private int size;
|
private int size;
|
||||||
private byte[]data;
|
private byte[]data;
|
||||||
private int sendcount;
|
private int sendcount;*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getHeaderSize() {
|
||||||
|
return super.getHeaderSize()+19;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getLength() {
|
||||||
|
return super.getLength()+19+data.limit();
|
||||||
|
}
|
||||||
|
|
||||||
volatile long resendtimer=System.nanoTime();
|
volatile long resendtimer=System.nanoTime();
|
||||||
|
|
||||||
public DATATPacket(int sport,int dport,long number,byte[]data,int size) {
|
private ByteBuffer data=KLALBPacket.databufferpool.borrow();
|
||||||
|
|
||||||
|
public DATATPacket(int sport,int dport,long number,int mtulimit) {
|
||||||
super(DATAT);
|
super(DATAT);
|
||||||
this.sport=sport;
|
/*this.sport=sport;
|
||||||
this.dport=dport;
|
this.dport=dport;
|
||||||
this.number=number;
|
this.number=number;
|
||||||
this.data=data;
|
this.data=data;
|
||||||
this.size=size;
|
this.size=size;*/
|
||||||
|
header.putInt(sport);
|
||||||
|
header.putInt(dport);
|
||||||
|
header.putLong(number);
|
||||||
|
header.put((byte) 0);
|
||||||
|
header.putChar((char) 0);
|
||||||
|
|
||||||
|
data.limit(mtulimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSendcount() {
|
public int getSendcount() {
|
||||||
return sendcount;
|
return header.get(17);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DATATPacket() {
|
public DATATPacket() {
|
||||||
super(DATAT);
|
super(DATAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DATATPacket(ByteBuffer bb) {
|
||||||
|
super(bb);
|
||||||
|
}
|
||||||
|
|
||||||
public int getSport() {
|
public int getSport() {
|
||||||
return sport;
|
return header.getInt(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getDport() {
|
public int getDport() {
|
||||||
return dport;
|
return header.getInt(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getNumber() {
|
public long getNumber() {
|
||||||
return number;
|
return header.getLong(9);
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getData() {
|
public ByteBuffer getDataBuffer() {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "DATAT "+sport+"->"+dport+" "+number+"["+size+"]";
|
return "DATAT "+getSport()+"->"+getDport()+" "+getNumber()+"["+getSize()+"]";
|
||||||
}
|
|
||||||
private final byte[] writeBuffer = new byte[19];
|
|
||||||
@Override
|
|
||||||
protected void writeToStream(DataOutput dto) throws IOException {
|
|
||||||
super.writeToStream(dto);
|
|
||||||
/*dto.writeInt(sport);
|
|
||||||
dto.writeInt(dport);
|
|
||||||
dto.writeLong(number);
|
|
||||||
dto.writeByte(getSendRecord().size());
|
|
||||||
dto.writeChar(size);*/
|
|
||||||
|
|
||||||
writeBuffer[0] = (byte)(sport >>> 24);
|
|
||||||
writeBuffer[1] = (byte)(sport >>> 16);
|
|
||||||
writeBuffer[2] = (byte)(sport >>> 8);
|
|
||||||
writeBuffer[3] = (byte)(sport >>> 0);
|
|
||||||
|
|
||||||
writeBuffer[4] = (byte)(dport >>> 24);
|
|
||||||
writeBuffer[5] = (byte)(dport >>> 16);
|
|
||||||
writeBuffer[6] = (byte)(dport >>> 8);
|
|
||||||
writeBuffer[7] = (byte)(dport >>> 0);
|
|
||||||
|
|
||||||
writeBuffer[8] = (byte)(number >>> 56);
|
|
||||||
writeBuffer[9] = (byte)(number >>> 48);
|
|
||||||
writeBuffer[10] = (byte)(number >>> 40);
|
|
||||||
writeBuffer[11] = (byte)(number >>> 32);
|
|
||||||
writeBuffer[12] = (byte)(number >>> 24);
|
|
||||||
writeBuffer[13] = (byte)(number >>> 16);
|
|
||||||
writeBuffer[14] = (byte)(number >>> 8);
|
|
||||||
writeBuffer[15] = (byte)(number >>> 0);
|
|
||||||
|
|
||||||
writeBuffer[16]=(byte) getSendRecord().size();
|
|
||||||
|
|
||||||
writeBuffer[17]=(byte) (size>>>8);
|
|
||||||
writeBuffer[18]=(byte) (size>>>0);
|
|
||||||
dto.write(writeBuffer);
|
|
||||||
//CRC32 crc=new CRC32();
|
|
||||||
// crc.update(data, 0, size);
|
|
||||||
dto.write(data,0,size);
|
|
||||||
//dto.writeLong(crc.getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
private final byte[] readBuffer = new byte[19];
|
|
||||||
@Override
|
|
||||||
protected void readFromStream(DataInput din) throws IOException {
|
|
||||||
super.readFromStream(din);
|
|
||||||
/*sport=din.readInt();
|
|
||||||
dport=din.readInt();
|
|
||||||
number=din.readLong();
|
|
||||||
sendcount=din.readUnsignedByte();
|
|
||||||
size=din.readChar();*/
|
|
||||||
|
|
||||||
din.readFully(readBuffer);
|
|
||||||
sport=((readBuffer[0] << 24) + (readBuffer[1] << 16) + (readBuffer[2] << 8) + (readBuffer[3] << 0));
|
|
||||||
dport=((readBuffer[4] << 24) + (readBuffer[5] << 16) + (readBuffer[6] << 8) + (readBuffer[7] << 0));
|
|
||||||
number=(((long)readBuffer[8] << 56) +
|
|
||||||
((long)(readBuffer[9] & 255) << 48) +
|
|
||||||
((long)(readBuffer[10] & 255) << 40) +
|
|
||||||
((long)(readBuffer[11] & 255) << 32) +
|
|
||||||
((long)(readBuffer[12] & 255) << 24) +
|
|
||||||
((readBuffer[13] & 255) << 16) +
|
|
||||||
((readBuffer[14] & 255) << 8) +
|
|
||||||
((readBuffer[15] & 255) << 0));
|
|
||||||
sendcount=readBuffer[16]&0xff;
|
|
||||||
size=(((readBuffer[17]&0xff) << 8) + ((readBuffer[18]&0xff) << 0));
|
|
||||||
|
|
||||||
data=arrayRecycle.create();
|
|
||||||
din.readFully(data,0,size);
|
|
||||||
/*CRC32 crc32=new CRC32();
|
|
||||||
crc32.update(data, 0, size);
|
|
||||||
if(din.readLong()!=crc32.getValue()) {
|
|
||||||
throw new StreamCorruptedException("CRC32 error!");
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(number);
|
return (int) getNumber();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (this == obj)
|
|
||||||
return true;
|
|
||||||
if (obj == null)
|
if (obj == null)
|
||||||
return false;
|
return false;
|
||||||
if (getClass() != obj.getClass())
|
try {
|
||||||
return false;
|
|
||||||
DATATPacket other = (DATATPacket) obj;
|
DATATPacket other = (DATATPacket) obj;
|
||||||
return number == other.number;
|
return getNumber() == other.getNumber();
|
||||||
|
}catch(ClassCastException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSize() {
|
public int getSize() {
|
||||||
return size;
|
return data.limit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(DATATPacket o) {
|
protected void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||||
if(number>o.number) {
|
header.put(17, (byte) getSendRecord().size());
|
||||||
return 1;
|
header.putChar(18, (char) data.limit());
|
||||||
}else if(number<o.number){
|
super.writeToChannel(dto);
|
||||||
return -1;
|
dto.write(data.slice(0, data.limit()));
|
||||||
}else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void readFromChannel(ReadableByteChannel din) throws IOException {
|
||||||
|
super.readFromChannel(din);
|
||||||
|
data.clear();
|
||||||
|
data.limit(header.getChar(18));
|
||||||
|
while(data.hasRemaining()){
|
||||||
|
if(din.read(data)==-1) {
|
||||||
|
throw new EOFException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data.flip();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispose() {
|
||||||
|
super.dispose();
|
||||||
|
ByteBuffer datan=data;
|
||||||
|
data=null;
|
||||||
|
KLALBPacket.databufferpool.back(datan);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.kne.cloud.network.klalb;
|
/*package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
@@ -7,13 +7,23 @@ import java.io.DataOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.DatagramPacket;
|
import java.net.DatagramPacket;
|
||||||
import java.net.DatagramSocket;
|
import java.net.DatagramSocket;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
|
|
||||||
|
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||||
|
import org.kne.cloud.network.SpeedLimiter;
|
||||||
|
|
||||||
public class DatagramKLALBPacketLink implements KLALBPacketLink {
|
public class DatagramKLALBPacketLink implements KLALBPacketLink {
|
||||||
|
|
||||||
|
private static final int MTU=1500;
|
||||||
|
|
||||||
|
private static final int HEAD=32;
|
||||||
|
|
||||||
|
private int packSign=0;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "DatagramKLALBPacketLink [ds=" + ds + "]";
|
return new MultipurposeSocketAddress("UDP",(InetSocketAddress)ds.getLocalSocketAddress())+"←"+new MultipurposeSocketAddress("UDP",(InetSocketAddress)ds.getRemoteSocketAddress());
|
||||||
}
|
}
|
||||||
|
|
||||||
private DatagramSocket ds;
|
private DatagramSocket ds;
|
||||||
@@ -27,22 +37,32 @@ public class DatagramKLALBPacketLink implements KLALBPacketLink {
|
|||||||
@Override
|
@Override
|
||||||
public void writePacket(KLALBPacket kp) throws IOException {
|
public void writePacket(KLALBPacket kp) throws IOException {
|
||||||
//System.out.println(" TX:"+kp);
|
//System.out.println(" TX:"+kp);
|
||||||
bos.reset();
|
|
||||||
KLALBOutputStream.writeKLALBPacketToStream(dos, kp);
|
KLALBOutputStream.writeKLALBPacketToStream(dos, kp);
|
||||||
byte[]bt=bos.toByteArray();
|
|
||||||
DatagramPacket dp=new DatagramPacket(bt,bt.length);
|
|
||||||
ds.send(dp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[]bc=new byte[65535];
|
private byte[]bc=new byte[65535];
|
||||||
|
DataInputStream dis;
|
||||||
@Override
|
@Override
|
||||||
public KLALBPacket readPacket() throws IOException {
|
public KLALBPacket readPacket() throws IOException {
|
||||||
DatagramPacket dp=new DatagramPacket(bc, bc.length);
|
KLALBPacket kp=null;
|
||||||
|
do {
|
||||||
|
if(dis==null) {
|
||||||
|
|
||||||
|
byte[]data=new byte[65535];
|
||||||
|
DatagramPacket dp=new DatagramPacket(data, data.length);
|
||||||
ds.receive(dp);
|
ds.receive(dp);
|
||||||
DataInputStream dis=new DataInputStream(new ByteArrayInputStream(bc, 0, dp.getLength()));
|
|
||||||
KLALBPacket kp=KLALBInputStream.readKLALBPacketFromStream(dis);
|
|
||||||
dis.close();
|
dis=new DataInputStream(new ByteArrayInputStream(bc, 0, dp.getLength()));
|
||||||
|
}
|
||||||
|
kp=KLALBInputStream.readKLALBPacketFromStream(dis);
|
||||||
|
if(kp!=null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
dis=null;
|
||||||
//System.out.println(" RX:"+kp);
|
//System.out.println(" RX:"+kp);
|
||||||
|
}while(true);
|
||||||
return kp;
|
return kp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,4 +85,130 @@ public class DatagramKLALBPacketLink implements KLALBPacketLink {
|
|||||||
public int getSoTimeout() throws SocketException {
|
public int getSoTimeout() throws SocketException {
|
||||||
return ds.getSoTimeout();
|
return ds.getSoTimeout();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void flush() throws IOException {
|
||||||
|
byte[]bt=bos.toByteArray();
|
||||||
|
bos.reset();
|
||||||
|
int seq=0;
|
||||||
|
int maxseq=(bt.length+MTU-HEAD-1)/(MTU-HEAD);
|
||||||
|
int startptr=0;
|
||||||
|
while(startptr<bt.length) {
|
||||||
|
int copysize=Math.min(bt.length-startptr,MTU-HEAD);
|
||||||
|
byte[]data=new byte[copysize+4];
|
||||||
|
data[2]=(byte) (packSign>>8);
|
||||||
|
data[3]=(byte) packSign;
|
||||||
|
data[4]=(byte)seq;
|
||||||
|
data[5]=(byte)maxseq;
|
||||||
|
System.arraycopy(bt, startptr, data, 6, copysize);
|
||||||
|
startptr+=copysize;
|
||||||
|
DatagramPacket dp=new DatagramPacket(data,data.length);
|
||||||
|
ds.send(dp);
|
||||||
|
}
|
||||||
|
packSign++;
|
||||||
|
packSign=packSign&0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isStream() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.DatagramPacket;
|
||||||
|
import java.net.DatagramSocket;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.SocketException;
|
||||||
|
|
||||||
|
import org.kne.cloud.network.DatagramServerSocket;
|
||||||
|
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||||
|
import org.kne.cloud.network.SpeedLimiter;
|
||||||
|
|
||||||
|
public class DatagramKLALBPacketLink implements KLALBPacketLink {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return new MultipurposeSocketAddress("UDP",(InetSocketAddress)ds.getLocalSocketAddress())+"←"+new MultipurposeSocketAddress("UDP",(InetSocketAddress)ds.getRemoteSocketAddress());
|
||||||
|
}
|
||||||
|
|
||||||
|
private DatagramSocket ds;
|
||||||
|
|
||||||
|
public DatagramKLALBPacketLink(DatagramSocket connectDatagramSocket) throws IOException {
|
||||||
|
this.ds=connectDatagramSocket;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ByteArrayOutputStream bos=new ByteArrayOutputStream(65535);
|
||||||
|
private DataOutputStream dos=new DataOutputStream(bos);
|
||||||
|
@Override
|
||||||
|
public void writePacket(KLALBPacket kp) throws IOException {
|
||||||
|
//System.out.println(" TX:"+kp);
|
||||||
|
KLALBPacket.writeKLALBPacketToStream(dos, kp);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[]bc=new byte[65535];
|
||||||
|
DataInputStream dis;
|
||||||
|
@Override
|
||||||
|
public KLALBPacket readPacket() throws IOException {
|
||||||
|
KLALBPacket kp=null;
|
||||||
|
do {
|
||||||
|
if(dis==null) {
|
||||||
|
if(ds instanceof DatagramServerSocket.SubDatagramSocket) {
|
||||||
|
DatagramPacket dp=((DatagramServerSocket.SubDatagramSocket) ds).receive();
|
||||||
|
dis=new DataInputStream(new ByteArrayInputStream(dp.getData(), 0, dp.getLength()));
|
||||||
|
}else {
|
||||||
|
DatagramPacket dp=new DatagramPacket(bc, bc.length);
|
||||||
|
ds.receive(dp);
|
||||||
|
dis=new DataInputStream(new ByteArrayInputStream(bc, 0, dp.getLength()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
kp=KLALBPacket.readKLALBPacketFromStream(dis);
|
||||||
|
if(kp!=null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
dis=null;
|
||||||
|
//System.out.println(" RX:"+kp);
|
||||||
|
}while(true);
|
||||||
|
return kp;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
ds.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isClosed() {
|
||||||
|
return ds.isClosed();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSoTimeout(int val) throws SocketException {
|
||||||
|
ds.setSoTimeout(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSoTimeout() throws SocketException {
|
||||||
|
return ds.getSoTimeout();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void flush() throws IOException {
|
||||||
|
byte[]bt=bos.toByteArray();
|
||||||
|
DatagramPacket dp=new DatagramPacket(bt,bt.length);
|
||||||
|
ds.send(dp);
|
||||||
|
bos.reset();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isStream() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package org.kne.cloud.network.klalb;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.BindException;
|
import java.net.BindException;
|
||||||
import java.net.ConnectException;
|
import java.net.ConnectException;
|
||||||
|
import java.net.Inet4Address;
|
||||||
import java.net.Inet6Address;
|
import java.net.Inet6Address;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
@@ -12,10 +13,13 @@ import java.net.Socket;
|
|||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
import java.net.SocketTimeoutException;
|
import java.net.SocketTimeoutException;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.time.Clock;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -23,10 +27,14 @@ import java.util.Map.Entry;
|
|||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
|
import java.util.TimerTask;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
import java.util.concurrent.locks.LockSupport;
|
||||||
import java.util.concurrent.locks.ReadWriteLock;
|
import java.util.concurrent.locks.ReadWriteLock;
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
@@ -37,11 +45,14 @@ import javax.management.openmbean.ArrayType;
|
|||||||
import javax.net.ServerSocketFactory;
|
import javax.net.ServerSocketFactory;
|
||||||
import javax.net.SocketFactory;
|
import javax.net.SocketFactory;
|
||||||
|
|
||||||
|
import org.kne.cloud.clock.AdjustedNanoClock;
|
||||||
import org.kne.cloud.network.MultipurposeSocketAddress;
|
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||||
import org.kne.cloud.network.NetworkService;
|
import org.kne.cloud.network.NetworkService;
|
||||||
import org.kne.cloud.network.Proxy;
|
import org.kne.cloud.network.Proxy;
|
||||||
import org.kne.cloud.network.SocketType;
|
import org.kne.cloud.network.SocketType;
|
||||||
import org.kne.cloud.network.ThreadTool;
|
import org.kne.cloud.network.ThreadTool;
|
||||||
|
import org.kne.cloud.network.monitor.MonitorData;
|
||||||
|
import org.kne.cloud.network.monitor.SpeedAndTrafficMonitorDataImpl;
|
||||||
import org.kne.debug.TimeDebugger;
|
import org.kne.debug.TimeDebugger;
|
||||||
|
|
||||||
import javassist.ClassPool;
|
import javassist.ClassPool;
|
||||||
@@ -52,11 +63,147 @@ import javassist.bytecode.CodeAttribute;
|
|||||||
import javassist.bytecode.CodeIterator;
|
import javassist.bytecode.CodeIterator;
|
||||||
|
|
||||||
public class KLALBController {
|
public class KLALBController {
|
||||||
|
|
||||||
|
private SpeedAndTrafficMonitorDataImpl linkMonitor=new SpeedAndTrafficMonitorDataImpl();
|
||||||
|
|
||||||
|
private SpeedAndTrafficMonitorDataImpl datatMonitor=new SpeedAndTrafficMonitorDataImpl();
|
||||||
|
|
||||||
|
private List<MultipurposeSocketAddress>selflineTable=new ArrayList<>();
|
||||||
|
private Timer twk=new Timer("网卡检测扫描计时器", true);
|
||||||
|
{
|
||||||
|
|
||||||
|
twk.schedule(new TimerTask() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
Enumeration<NetworkInterface>eu= NetworkInterface.getNetworkInterfaces();
|
||||||
|
while (eu.hasMoreElements()) {
|
||||||
|
NetworkInterface networkInterface = (NetworkInterface) eu.nextElement();
|
||||||
|
if(networkInterface.isUp()) {
|
||||||
|
//System.out.println(networkInterface+" "+networkInterface.isUp());
|
||||||
|
Enumeration<InetAddress>ei= networkInterface.getInetAddresses();
|
||||||
|
while (ei.hasMoreElements()) {
|
||||||
|
InetAddress inetAddress = (InetAddress) ei.nextElement();
|
||||||
|
|
||||||
|
for (Iterator<MultipurposeSocketAddress> iterator = listens.iterator(); iterator.hasNext();) {
|
||||||
|
MultipurposeSocketAddress tcpl = (MultipurposeSocketAddress) iterator.next();
|
||||||
|
|
||||||
|
try {
|
||||||
|
if(tcpl.getInetAddress().isAnyLocalAddress()||tcpl.getInetAddress().equals(inetAddress)) {
|
||||||
|
MultipurposeSocketAddress bind=new MultipurposeSocketAddress(tcpl.getType(),inetAddress.getHostAddress(),tcpl.getPort());
|
||||||
|
//System.out.println(bind);
|
||||||
|
synchronized (selflineTable) {
|
||||||
|
if(!selflineTable.contains(bind)) {
|
||||||
|
selflineTable.add(bind);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (UnknownHostException e) {
|
||||||
|
// TODO 自动生成的 catch 块
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SocketException e) {
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
List<MultipurposeSocketAddress>localaddress=new ArrayList<>();
|
||||||
|
Enumeration<NetworkInterface>eu= NetworkInterface.getNetworkInterfaces();
|
||||||
|
while (eu.hasMoreElements()) {
|
||||||
|
NetworkInterface networkInterface = (NetworkInterface) eu.nextElement();
|
||||||
|
if(networkInterface.isUp()) {
|
||||||
|
//System.out.println(networkInterface+" "+networkInterface.isUp());
|
||||||
|
Enumeration<InetAddress>ei= networkInterface.getInetAddresses();
|
||||||
|
while (ei.hasMoreElements()) {
|
||||||
|
InetAddress inetAddress = (InetAddress) ei.nextElement();
|
||||||
|
MultipurposeSocketAddress bind=new MultipurposeSocketAddress(inetAddress.getHostAddress(),0);
|
||||||
|
localaddress.add(bind);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Set<MultipurposeSocketAddress>st=new HashSet<>();
|
||||||
|
for (Iterator<KLALBRemoteLine> iterator = lines.iterator(); iterator.hasNext();) {
|
||||||
|
KLALBRemoteLine multipurposeSocketAddress = (KLALBRemoteLine) iterator.next();
|
||||||
|
if(multipurposeSocketAddress.getSocketAddress()!=null)
|
||||||
|
st.add(multipurposeSocketAddress.getSocketAddress());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (Iterator<MultipurposeSocketAddress> iterator = st.iterator(); iterator.hasNext();) {
|
||||||
|
MultipurposeSocketAddress multipurposeSocketAddress = (MultipurposeSocketAddress) iterator
|
||||||
|
.next();
|
||||||
|
for (Iterator<MultipurposeSocketAddress> iterator2 = localaddress.iterator(); iterator2.hasNext();) {
|
||||||
|
MultipurposeSocketAddress bind = (MultipurposeSocketAddress) iterator2
|
||||||
|
.next();
|
||||||
|
try {
|
||||||
|
if(multipurposeSocketAddress.getInetAddress()instanceof Inet4Address&&bind.getInetAddress() instanceof Inet6Address) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(multipurposeSocketAddress.getInetAddress() instanceof Inet6Address &&bind.getInetAddress() instanceof Inet4Address) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} catch (UnknownHostException e) {
|
||||||
|
}
|
||||||
|
if(!checkContainsTargetAndBind(multipurposeSocketAddress,bind)) {
|
||||||
|
//System.out.println(target+" "+bind);
|
||||||
|
addRemoteLine( new KLALBRemoteLine(multipurposeSocketAddress,bind));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
for (Iterator<KLALBRemoteLine> iterator = lines.iterator(); iterator.hasNext();) {
|
||||||
|
KLALBRemoteLine reml = (KLALBRemoteLine) iterator
|
||||||
|
.next();
|
||||||
|
if(reml.getSocketAddress()!=null) {
|
||||||
|
if(reml.getBindAddress()!=null||reml.getRemoteVaddr()!=null)
|
||||||
|
if(!localaddress.contains(reml.getBindAddress())) {
|
||||||
|
reml.close();
|
||||||
|
lines.remove(reml);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (SocketException e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}, 2000, 2000);
|
||||||
|
}
|
||||||
|
public SpeedAndTrafficMonitorDataImpl getLinkMonitor() {
|
||||||
|
return linkMonitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SpeedAndTrafficMonitorDataImpl getDatatMonitor() {
|
||||||
|
return datatMonitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ConcurrentHashMap<Inet6Address, AdjustedNanoClock>clocks=new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
protected AdjustedNanoClock getAdjustedClockByVaddr(Inet6Address vaddr) {
|
||||||
|
AdjustedNanoClock clk=clocks.get(vaddr);
|
||||||
|
if(clk==null) {
|
||||||
|
clk=new AdjustedNanoClock();
|
||||||
|
clocks.put(vaddr, clk);
|
||||||
|
}
|
||||||
|
return clk;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private SocketType socketType= new KLALBSocketType();
|
private SocketType socketType= new KLALBSocketType();
|
||||||
|
|
||||||
public class KLALBSocketType extends SocketType{
|
public class KLALBSocketType extends SocketType{
|
||||||
|
|
||||||
public KLALBSocketType() {
|
public KLALBSocketType() {
|
||||||
super(new KLALBVirtualSocketFactory(KLALBController.this), new KLALBVirtualServerSocketFactory(KLALBController.this));
|
super(new KLALBVirtualSocketFactory(KLALBController.this), new KLALBVirtualServerSocketFactory(KLALBController.this),new KLALBVirtualSocketChannelFactory(KLALBController.this), new KLALBVirtualServerSocketChannelFactory(KLALBController.this));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -64,23 +211,30 @@ public class KLALBController {
|
|||||||
return socketType;
|
return socketType;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Supplier<String> selflineTableSupplier=()->{return null;};
|
|
||||||
|
|
||||||
|
//private Supplier<String> selflineTableSupplier=()->{return null;};
|
||||||
|
|
||||||
|
|
||||||
public Supplier<String> getSelflineTableSupplier() {
|
/*public Supplier<String> getSelflineTableSupplier() {
|
||||||
return selflineTableSupplier;
|
return selflineTableSupplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSelflineTableSupplier(Supplier<String> selflineTableSupplier) {
|
public void setSelflineTableSupplier(Supplier<String> selflineTableSupplier) {
|
||||||
this.selflineTableSupplier = selflineTableSupplier;
|
this.selflineTableSupplier = selflineTableSupplier;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
public List<MultipurposeSocketAddress> getSelflineTable() {
|
||||||
|
return selflineTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private Inet6Address self;
|
private Inet6Address self;
|
||||||
|
|
||||||
public Inet6Address getSelf() {
|
public Inet6Address getSelf() {
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
private List<KLALBRemoteLine> lines=new ArrayList<>();
|
private List<KLALBRemoteLine> lines=new CopyOnWriteArrayList<>();
|
||||||
//private ReadWriteLock lineslock=new ReentrantReadWriteLock();
|
//private ReadWriteLock lineslock=new ReentrantReadWriteLock();
|
||||||
|
|
||||||
public List<KLALBRemoteLine> getLines() {
|
public List<KLALBRemoteLine> getLines() {
|
||||||
@@ -95,12 +249,10 @@ public class KLALBController {
|
|||||||
|
|
||||||
|
|
||||||
public void reconnectImmediately() {
|
public void reconnectImmediately() {
|
||||||
synchronized (lines) {
|
|
||||||
for (Iterator<KLALBRemoteLine> iterator = lines.iterator(); iterator.hasNext();) {
|
for (Iterator<KLALBRemoteLine> iterator = lines.iterator(); iterator.hasNext();) {
|
||||||
KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) iterator.next();
|
KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) iterator.next();
|
||||||
klalbRemoteLine.reconnectImmediately();
|
klalbRemoteLine.reconnectImmediately();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private PacketReceiver prc=new PacketReceiver();
|
private PacketReceiver prc=new PacketReceiver();
|
||||||
@@ -113,21 +265,26 @@ public class KLALBController {
|
|||||||
PortPacket pt=(PortPacket) rec;
|
PortPacket pt=(PortPacket) rec;
|
||||||
if(!streamPortBinder.distributePacketToConsumer(krs, pt)) {
|
if(!streamPortBinder.distributePacketToConsumer(krs, pt)) {
|
||||||
if(!(pt instanceof RSTPacket))
|
if(!(pt instanceof RSTPacket))
|
||||||
sendPacketToAddress(krs.getRemoteVaddr(), new RSTPacket(pt.getDport(), pt.getSport()),
|
sendPacketToAddress(krs.getRemoteVaddr(), new RSTPacket(pt.getDport(), pt.getSport()),2);
|
||||||
0,2);
|
|
||||||
}
|
}
|
||||||
}else {
|
}else {
|
||||||
switch (rec.getType()) {
|
switch (rec.getType()) {
|
||||||
case KLALBPacket.ADDLINES:
|
case KLALBPacket.ADDLINES:
|
||||||
ADDLINESPacket lpt=(ADDLINESPacket) rec;
|
ADDLINESPacket lpt=(ADDLINESPacket) rec;
|
||||||
String s=lpt.getLines();
|
String s=lpt.getLines();
|
||||||
|
ThreadTool.makeVDaemonThreadIfSupport("线路添加任务", ()->{
|
||||||
Scanner scn=new Scanner(s);
|
Scanner scn=new Scanner(s);
|
||||||
while(scn.hasNext()) {
|
while(scn.hasNext()) {
|
||||||
String sn=scn.nextLine();
|
String sn=scn.nextLine();
|
||||||
MultipurposeSocketAddress msa= new MultipurposeSocketAddress(sn);
|
MultipurposeSocketAddress msa= new MultipurposeSocketAddress(sn);
|
||||||
addRemoteLines(msa);
|
try {
|
||||||
|
addRemoteLines(msa);
|
||||||
|
} catch (SocketTimeoutException e) {
|
||||||
|
} catch (SocketException e) {
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}).start();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -142,7 +299,6 @@ public class KLALBController {
|
|||||||
|
|
||||||
}
|
}
|
||||||
public void addRemoteLines(MultipurposeSocketAddress target) throws SocketTimeoutException, SocketException {
|
public void addRemoteLines(MultipurposeSocketAddress target) throws SocketTimeoutException, SocketException {
|
||||||
synchronized (lines) {
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Enumeration<NetworkInterface>eu= NetworkInterface.getNetworkInterfaces();
|
Enumeration<NetworkInterface>eu= NetworkInterface.getNetworkInterfaces();
|
||||||
@@ -154,6 +310,15 @@ public class KLALBController {
|
|||||||
while (ei.hasMoreElements()) {
|
while (ei.hasMoreElements()) {
|
||||||
InetAddress inetAddress = (InetAddress) ei.nextElement();
|
InetAddress inetAddress = (InetAddress) ei.nextElement();
|
||||||
MultipurposeSocketAddress bind=new MultipurposeSocketAddress(inetAddress.getHostAddress(),0);
|
MultipurposeSocketAddress bind=new MultipurposeSocketAddress(inetAddress.getHostAddress(),0);
|
||||||
|
try {
|
||||||
|
if(target.getInetAddress()instanceof Inet4Address&&bind.getInetAddress() instanceof Inet6Address) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(target.getInetAddress() instanceof Inet6Address &&bind.getInetAddress() instanceof Inet4Address) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} catch (UnknownHostException e) {
|
||||||
|
}
|
||||||
if(!checkContainsTargetAndBind(target,bind)) {
|
if(!checkContainsTargetAndBind(target,bind)) {
|
||||||
//System.out.println(target+" "+bind);
|
//System.out.println(target+" "+bind);
|
||||||
addRemoteLine( new KLALBRemoteLine(target,bind));
|
addRemoteLine( new KLALBRemoteLine(target,bind));
|
||||||
@@ -164,21 +329,21 @@ public class KLALBController {
|
|||||||
} catch (SocketException e) {
|
} catch (SocketException e) {
|
||||||
if(!checkContainsTarget(target))
|
if(!checkContainsTarget(target))
|
||||||
addRemoteLine( new KLALBRemoteLine(target));
|
addRemoteLine( new KLALBRemoteLine(target));
|
||||||
throw e;
|
//throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
public Inet6Address getRemoteVaddrBySocketAddress(MultipurposeSocketAddress target) throws SocketTimeoutException {
|
public Inet6Address getRemoteVaddrBySocketAddress(MultipurposeSocketAddress target) throws SocketTimeoutException {
|
||||||
KLALBRemoteLine kr=null;
|
KLALBRemoteLine kr=null;
|
||||||
synchronized(lines) {
|
for (Iterator<KLALBRemoteLine> iterator = lines.iterator(); iterator.hasNext();) {
|
||||||
for (Iterator iterator = lines.iterator(); iterator.hasNext();) {
|
|
||||||
KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) iterator.next();
|
KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) iterator.next();
|
||||||
if(target.equals(klalbRemoteLine.getSocketAddress())) {
|
if(target.equals(klalbRemoteLine.getSocketAddress())&&klalbRemoteLine.getBindAddress()==null) {
|
||||||
kr=klalbRemoteLine;
|
kr=klalbRemoteLine;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if(kr==null) {
|
if(kr==null) {
|
||||||
kr=new KLALBRemoteLine(target);
|
kr=new KLALBRemoteLine(target);
|
||||||
addRemoteLine(kr);
|
addRemoteLine(kr);
|
||||||
@@ -213,19 +378,28 @@ public class KLALBController {
|
|||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addRemoteLine(KLALBRemoteLine krs) throws SocketTimeoutException {
|
public void addRemoteLine(KLALBRemoteLine krs) {
|
||||||
krs.setPacketReceiver(prc);
|
krs.setPacketReceiver(prc);
|
||||||
|
krs.setKlalbController(this);
|
||||||
krs.setLocalVaddrSupplier(()->{return self;});
|
krs.setLocalVaddrSupplier(()->{return self;});
|
||||||
krs.startIO();
|
krs.startIO();
|
||||||
String selflineTable=selflineTableSupplier.get();
|
String selflineTable=generateSelfLineTable();
|
||||||
if(selflineTable!=null)
|
if(selflineTable!=null&&!selflineTable.equals(""))
|
||||||
krs.sendPacket(new ADDLINESPacket(selflineTable), 0);
|
krs.sendPacket(new ADDLINESPacket(selflineTable));
|
||||||
synchronized (lines) {
|
|
||||||
lines.add(krs);
|
lines.add(krs);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private String generateSelfLineTable() {
|
||||||
|
StringBuilder sbd=new StringBuilder();
|
||||||
|
for (Iterator<MultipurposeSocketAddress> iterator = selflineTable.iterator(); iterator.hasNext();) {
|
||||||
|
MultipurposeSocketAddress klalbRemoteLine = (MultipurposeSocketAddress) iterator.next();
|
||||||
|
sbd.append(klalbRemoteLine.toString());
|
||||||
|
sbd.append('\n');
|
||||||
|
}
|
||||||
|
return sbd.toString();
|
||||||
|
}
|
||||||
|
|
||||||
public KLALBController(Inet6Address self) {
|
public KLALBController(Inet6Address self) {
|
||||||
this.self = self;
|
this.self = self;
|
||||||
}
|
}
|
||||||
@@ -238,16 +412,51 @@ public class KLALBController {
|
|||||||
return new KLALBVirtualSocketImpl(this);
|
return new KLALBVirtualSocketImpl(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected void sendPacketToAddress(Inet6Address addr, KLALBPacket syntPacket, int priority)
|
protected void sendPacketToAddress(Inet6Address addr, KLALBPacket packet)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
sendPacketToAddress(addr, syntPacket, priority, 1);
|
sendPacketToAddress(addr, packet, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Timer trtr=new Timer("路由表刷新计时器", true);
|
||||||
|
{
|
||||||
|
trtr.scheduleAtFixedRate(new TimerTask() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
Map<Inet6Address,List<KLALBRemoteLine>> lines2 =new ConcurrentHashMap<>();
|
||||||
|
for (Iterator<KLALBRemoteLine> iterator = lines.iterator(); iterator.hasNext();) {
|
||||||
|
KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) iterator.next();
|
||||||
|
if(klalbRemoteLine.isClosed()) {
|
||||||
|
lines.remove(klalbRemoteLine);
|
||||||
|
}else {
|
||||||
|
if(klalbRemoteLine.getRemoteVaddr()!=null&&klalbRemoteLine.getMonitor().getState()==MonitorData.ONLINE) {
|
||||||
|
if(lines2.containsKey(klalbRemoteLine.getRemoteVaddr())) {
|
||||||
|
lines2.get(klalbRemoteLine.getRemoteVaddr()).add(klalbRemoteLine);
|
||||||
|
}else {
|
||||||
|
ArrayList<KLALBRemoteLine>al1=new ArrayList<>();
|
||||||
|
al1.add(klalbRemoteLine);
|
||||||
|
lines2.put(klalbRemoteLine.getRemoteVaddr(), al1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Iterator<Entry<Inet6Address, List<KLALBRemoteLine>>> iterator = lines2.entrySet().iterator(); iterator.hasNext();) {
|
||||||
|
Entry<Inet6Address, List<KLALBRemoteLine>> klalbRemoteLine = (Entry<Inet6Address, List<KLALBRemoteLine>>) iterator.next();
|
||||||
|
klalbRemoteLine.getValue().forEach((r)->{
|
||||||
|
r.runPredict();
|
||||||
|
});
|
||||||
|
Collections.sort(klalbRemoteLine.getValue());
|
||||||
|
}
|
||||||
|
KLALBController.this.lines2=lines2;
|
||||||
|
}
|
||||||
|
}, 5, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateLines2(Inet6Address addr) throws SocketTimeoutException {
|
private void updateLines2(Inet6Address addr) throws SocketTimeoutException {
|
||||||
List<KLALBRemoteLine> l=new ArrayList();
|
List<KLALBRemoteLine> l=new ArrayList();
|
||||||
synchronized (lines) {
|
|
||||||
for (int i = 0; i < lines.size(); i++) {
|
for (int i = 0; i < lines.size(); i++) {
|
||||||
KLALBRemoteLine klalbRemoteLine = lines.get(i);
|
KLALBRemoteLine klalbRemoteLine = lines.get(i);
|
||||||
if(klalbRemoteLine.isClosed()) {
|
if(klalbRemoteLine.isClosed()) {
|
||||||
@@ -255,103 +464,120 @@ public class KLALBController {
|
|||||||
i--;
|
i--;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(addr.equals(klalbRemoteLine.getRemoteVaddr())&&klalbRemoteLine.getMonitor().getState()==Monitor.ONLINE) {
|
if(addr.equals(klalbRemoteLine.getRemoteVaddr())&&klalbRemoteLine.getMonitor().getState()==MonitorData.ONLINE) {
|
||||||
l.add(klalbRemoteLine);
|
l.add(klalbRemoteLine);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if(l.isEmpty()) {
|
if(l.isEmpty()) {
|
||||||
lines2.remove(addr);
|
lines2.remove(addr);
|
||||||
}else {
|
}else {
|
||||||
|
l.forEach((r)->{
|
||||||
|
r.runPredict();
|
||||||
|
});
|
||||||
|
Collections.sort(l);
|
||||||
lines2.put(addr, l);
|
lines2.put(addr, l);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private Map<Inet6Address,List<KLALBRemoteLine>> lines2 = new ConcurrentHashMap<>();
|
private Map<Inet6Address,List<KLALBRemoteLine>> lines2 = new ConcurrentHashMap<>();
|
||||||
private volatile long itm=System.nanoTime();
|
|
||||||
protected void sendPacketToAddress(Inet6Address addr, KLALBPacket packet, int priority, int count)
|
|
||||||
|
protected void sendPacketToAddress(Inet6Address addr, KLALBPacket packet, int count)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
/*if(packet instanceof RSTPacket) {
|
if(packet==null)
|
||||||
new Exception("-RST-").printStackTrace();
|
throw new NullPointerException("packet is null!");
|
||||||
}*/
|
|
||||||
//TimeDebugger tdb=new TimeDebugger();
|
//TimeDebugger tdb=new TimeDebugger();
|
||||||
//tdb.putTime("start");
|
|
||||||
|
|
||||||
|
|
||||||
|
//tdb.putTime("start");
|
||||||
|
packet.genseq();
|
||||||
|
loop:while(true) {
|
||||||
|
if(packet.isDisposed())
|
||||||
|
return;
|
||||||
List<KLALBRemoteLine> lines2x;
|
List<KLALBRemoteLine> lines2x;
|
||||||
//loop:while(true) {
|
|
||||||
long cur=System.nanoTime();
|
|
||||||
if(cur-itm>10000000L) {
|
|
||||||
itm=cur;
|
|
||||||
lines2.clear();
|
|
||||||
}
|
|
||||||
lines2x=lines2.get(addr);
|
lines2x=lines2.get(addr);
|
||||||
if (lines2x == null || lines2x.isEmpty()) {
|
|
||||||
updateLines2(addr);
|
|
||||||
lines2x=lines2.get(addr);
|
|
||||||
}
|
|
||||||
if (lines2x == null || lines2x.isEmpty()) {
|
if (lines2x == null || lines2x.isEmpty()) {
|
||||||
throw new NoRouteToHostException("address unreachable: " + addr);
|
throw new NoRouteToHostException("address unreachable: " + addr);
|
||||||
}
|
}
|
||||||
//tdb.putTime("selectLines");
|
|
||||||
/* for (Iterator<KLALBRemoteLine> iterator = lines2x.iterator(); iterator.hasNext();) {
|
|
||||||
KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) iterator.next();
|
|
||||||
if(klalbRemoteLine.statLengthBefore(priority)<=65536*10) {
|
|
||||||
break loop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
//System.out.println("slp");
|
|
||||||
Thread.sleep(1);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
List<KLALBRemoteLine> l2 = (List<KLALBRemoteLine>) ((ArrayList<KLALBRemoteLine>) lines2x).clone();
|
|
||||||
l2.removeAll(packet.getSendRecord());
|
|
||||||
if(l2.isEmpty()) {
|
|
||||||
l2 = (List<KLALBRemoteLine>) ((ArrayList<KLALBRemoteLine>) lines2x).clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
//tdb.putTime("findAvaliable");
|
|
||||||
|
|
||||||
int count0 = Math.min(count, l2.size());
|
int count0 = Math.min(count, lines2x.size());
|
||||||
l2.forEach((r)->{
|
|
||||||
r.runPredict(packet,priority);
|
for (int i = 0; i < lines2x.size(); i++) {
|
||||||
});
|
KLALBRemoteLine krst =lines2x.get(i);
|
||||||
//Collections.shuffle(l2);
|
if(krst.getMonitor().getState()==MonitorData.ONLINE)
|
||||||
Collections.sort(l2);
|
if(!packet.getSendRecord().contains(krst)) {
|
||||||
//tdb.putTime("makeDecision");
|
if(krst.getQueue().size()<3) {
|
||||||
//System.out.println(l2);
|
|
||||||
for (int i = 0; i < l2.size(); i++) {
|
|
||||||
KLALBRemoteLine krst =l2.get(i);
|
|
||||||
krst.sendPacket(packet, priority);
|
|
||||||
packet.getSendRecord().add(krst);
|
packet.getSendRecord().add(krst);
|
||||||
|
krst.sendPacket(packet);
|
||||||
count0--;
|
count0--;
|
||||||
if (count0 <= 0)
|
if (count0 <= 0)
|
||||||
break;
|
break loop;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//tdb.putTime("sendPacket");
|
for (int i = 0; i < lines2x.size(); i++) {
|
||||||
//tdb.print();
|
KLALBRemoteLine krst =lines2x.get(i);
|
||||||
/*if(packet instanceof RSTPacket)
|
if(krst.getMonitor().getState()==MonitorData.ONLINE)
|
||||||
new Exception().printStackTrace();*/
|
if(packet.getSendRecord().contains(krst)) {
|
||||||
}
|
if(krst.getQueue().size()<3) {
|
||||||
protected void removeFromSend(Inet6Address addr,KLALBPacket klalbPacket) {
|
packet.getSendRecord().add(krst);
|
||||||
synchronized (lines) {
|
krst.sendPacket(packet);
|
||||||
for (Iterator<KLALBRemoteLine> iterator = lines.iterator(); iterator.hasNext();) {
|
count0--;
|
||||||
KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) iterator.next();
|
if (count0 <= 0)
|
||||||
klalbRemoteLine.remoeFromSendQueue(klalbPacket);
|
break loop;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
LockSupport.parkNanos(50000);
|
||||||
|
//tdb.putTime("sendfailed");
|
||||||
|
}
|
||||||
|
//tdb.putTime("sendsuccess");
|
||||||
|
//tdb.print();
|
||||||
|
|
||||||
|
/* List<KLALBRemoteLine> lines2x;
|
||||||
|
lines2x=lines2.get(addr);
|
||||||
|
|
||||||
|
if (lines2x == null || lines2x.isEmpty()) {
|
||||||
|
throw new NoRouteToHostException("address unreachable: " + addr);
|
||||||
}
|
}
|
||||||
|
KLALBRemoteLine kr= lines2x.get(0);
|
||||||
|
kr.sendPacket(packet);
|
||||||
|
packet.getSendRecord().add(kr);*/
|
||||||
}
|
}
|
||||||
private Timer t=new Timer("数据包发送计时器", true);
|
/*protected void removeFromSend(Inet6Address addr,KLALBPacket klalbPacket) {
|
||||||
public Timer getTimer() {
|
for (Iterator iterator = lines.iterator(); iterator.hasNext();) {
|
||||||
|
KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) iterator.next();
|
||||||
|
klalbRemoteLine.remoeFromSendQueue(klalbPacket);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}*/
|
||||||
|
private Timer t=new Timer("数据包重传计时器", true);
|
||||||
|
public Timer getResendTimer() {
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
private Timer t2=new Timer("数据包粘包计时器", true);
|
||||||
|
|
||||||
|
private List<MultipurposeSocketAddress> listens=new CopyOnWriteArrayList<>();
|
||||||
|
|
||||||
|
public Timer getNagleTimer() {
|
||||||
|
return t2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void registerToProxyTypeAs(String proxyname) {
|
public void registerToProxyTypeAs(String proxyname) {
|
||||||
MultipurposeSocketAddress.getSocketTypeRegister().put(proxyname+"_Stream",socketType);
|
MultipurposeSocketAddress.getSocketTypeRegister().put(proxyname+"_Stream",socketType);
|
||||||
//ProxyProfileEntry.getRegister().put(proxyname, this);
|
//ProxyProfileEntry.getRegister().put(proxyname, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public List<MultipurposeSocketAddress> getListenSocketAddress() {
|
||||||
|
return listens;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*@Override
|
/*@Override
|
||||||
|
|||||||
@@ -24,68 +24,7 @@ public class KLALBInputStream extends DataInputStream {
|
|||||||
throw new StreamCorruptedException("remote version is V"+bv+"."+sv+",not V2.0");
|
throw new StreamCorruptedException("remote version is V"+bv+"."+sv+",not V2.0");
|
||||||
}
|
}
|
||||||
public KLALBPacket readPacket() throws IOException {
|
public KLALBPacket readPacket() throws IOException {
|
||||||
return readKLALBPacketFromStream(this);
|
return KLALBPacket.readKLALBPacketFromStream(this);
|
||||||
}
|
|
||||||
public static KLALBPacket readKLALBPacketFromStream(DataInputStream in) throws IOException {
|
|
||||||
int type=in.read();
|
|
||||||
|
|
||||||
if(type==-1) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
KLALBPacket klp;
|
|
||||||
switch(type) {
|
|
||||||
case PING:klp=new PINGPacket();
|
|
||||||
klp.readFromStream(in);
|
|
||||||
return klp;
|
|
||||||
case PONG:
|
|
||||||
klp=new PONGPacket();
|
|
||||||
klp.readFromStream(in);
|
|
||||||
return klp;
|
|
||||||
case SYNT:
|
|
||||||
klp=new SYNTPacket();
|
|
||||||
klp.readFromStream(in);
|
|
||||||
return klp;
|
|
||||||
case SACKT:
|
|
||||||
klp=new SACKTPacket();
|
|
||||||
klp.readFromStream(in);
|
|
||||||
return klp;
|
|
||||||
case RST:
|
|
||||||
klp=new RSTPacket();
|
|
||||||
klp.readFromStream(in);
|
|
||||||
return klp;
|
|
||||||
case DATAT:
|
|
||||||
klp=new DATATPacket();
|
|
||||||
klp.readFromStream(in);
|
|
||||||
return klp;
|
|
||||||
case ACKT:
|
|
||||||
klp=new ACKTPacket();
|
|
||||||
klp.readFromStream(in);
|
|
||||||
return klp;
|
|
||||||
case VADDR:
|
|
||||||
klp=new VADDRPacket();
|
|
||||||
klp.readFromStream(in);
|
|
||||||
return klp;
|
|
||||||
case ADDLINES:
|
|
||||||
klp=new ADDLINESPacket();
|
|
||||||
klp.readFromStream(in);
|
|
||||||
return klp;
|
|
||||||
case NACKT:
|
|
||||||
klp=new NACKTPacket();
|
|
||||||
klp.readFromStream(in);
|
|
||||||
return klp;
|
|
||||||
case TEST:
|
|
||||||
klp=new TESTPacket();
|
|
||||||
klp.readFromStream(in);
|
|
||||||
return klp;
|
|
||||||
case VADDRACK:
|
|
||||||
klp=new VADDRACKPacket();
|
|
||||||
klp.readFromStream(in);
|
|
||||||
return klp;
|
|
||||||
case VADDRREQ:
|
|
||||||
klp=new VADDRREQPacket();
|
|
||||||
klp.readFromStream(in);
|
|
||||||
return klp;
|
|
||||||
}
|
|
||||||
throw new StreamCorruptedException("unknown package type:"+type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,46 +1,53 @@
|
|||||||
package org.kne.cloud.network.klalb;
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileReader;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
|
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||||
import org.kne.cloud.network.KLALBProxyConfigJsonExecuter;
|
|
||||||
import org.kne.cloud.network.SocketToServiceProxy;
|
|
||||||
import org.kne.cloud.network.SocketToSocketProxy;
|
|
||||||
|
|
||||||
public class KLALBMain {
|
public class KLALBMain {
|
||||||
|
public static KLALBStateGUI2 ksg;
|
||||||
public static void main(String[] args) throws IOException {
|
public static void main(String[] args) throws IOException {
|
||||||
System.out.println(CONST.klalb+" V"+CONST.klalbver);
|
System.out.println(CONST.klalb+" V"+CONST.klalbver);
|
||||||
Scanner scn=new Scanner(System.in);
|
Scanner scn=new Scanner(System.in);
|
||||||
|
|
||||||
File configJson=new File("klalbconfig.json");
|
File configJson=new File("klalbconfig.json");
|
||||||
|
|
||||||
KLALBProxyConfigJsonExecuter kpcje=new KLALBProxyConfigJsonExecuter();
|
KLALBProxySystem kpcje=new KLALBProxySystem();
|
||||||
kpcje.loadConfigJson(configJson);
|
kpcje.loadConfigJson(configJson);
|
||||||
|
MultipurposeSocketAddress mpa=new MultipurposeSocketAddress("127.9.9.9", 49573);
|
||||||
|
kpcje.enableRemoteManagement(mpa);
|
||||||
|
System.out.println("远程管理端口已在"+mpa+"端口上开启");
|
||||||
while(true) {
|
while(true) {
|
||||||
String s=scn.next();
|
String s=scn.next();
|
||||||
String[]sc=s.split(" ");
|
String[]sc=s.split(" ");
|
||||||
switch(sc[0]) {
|
switch(sc[0]) {
|
||||||
|
case "?":
|
||||||
case "help":
|
case "help":
|
||||||
System.out.print("help:查看命令使用说明");
|
System.out.println("help:查看命令使用说明");
|
||||||
System.out.print("state:查看线路状态");
|
System.out.println("state:查看线路状态");
|
||||||
//System.out.println("reload:重新加载线路配置文件");
|
//System.out.println("reload:重新加载线路配置文件");
|
||||||
System.out.println("reconnect:所有离线线路跳过重连等待时间立即尝试重连");
|
System.out.println("reconnect:所有离线线路跳过重连等待时间立即尝试重连");
|
||||||
|
System.out.println("monitor:显示监视器图形界面");
|
||||||
System.out.println("stop:退出程序");
|
System.out.println("stop:退出程序");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "monitor":
|
||||||
|
if(ksg==null)
|
||||||
|
ksg=kpcje.getKLALBGUI();
|
||||||
|
ksg.setVisible(true);
|
||||||
|
break;
|
||||||
case "state":
|
case "state":
|
||||||
System.out.println("状态\t上传流量\t下载流量\t上传速度\t下载速度\t延迟\t抖动\t下一次重试");
|
System.out.println("状态\t可靠性\t上传流量\t下载流量\t上传速度\t下载速度\t上传延迟\t下载延迟\t上传抖动\t下载抖动");
|
||||||
|
synchronized (kpcje.getKlalbController().getLines()) {
|
||||||
for (Iterator<KLALBRemoteLine> iterator = kpcje.getKlalbController().getLines().iterator(); iterator.hasNext();) {
|
for (Iterator<KLALBRemoteLine> iterator = kpcje.getKlalbController().getLines().iterator(); iterator.hasNext();) {
|
||||||
KLALBRemoteLine hostPort = iterator.next();
|
KLALBRemoteLine hostPort = iterator.next();
|
||||||
System.out.println(hostPort .toString2());
|
System.out.println(hostPort .toString());
|
||||||
//System.out.println();
|
//System.out.println();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case "stop":
|
case "stop":
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
@@ -49,7 +56,7 @@ public class KLALBMain {
|
|||||||
kpcje.getKlalbController().reconnectImmediately();
|
kpcje.getKlalbController().reconnectImmediately();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
System.out.println("未知命令,请输入help以查询指令说明");
|
System.out.println("未知命令,请输入help以查询命令说明");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,11 +16,7 @@ public class KLALBOutputStream extends DataOutputStream {
|
|||||||
flush();
|
flush();
|
||||||
}
|
}
|
||||||
public void writePacket(KLALBPacket klb) throws IOException {
|
public void writePacket(KLALBPacket klb) throws IOException {
|
||||||
writeKLALBPacketToStream(this, klb);
|
KLALBPacket.writeKLALBPacketToStream(this, klb);
|
||||||
}
|
|
||||||
public static void writeKLALBPacketToStream(DataOutputStream out,KLALBPacket klb) throws IOException {
|
|
||||||
out.write(klb.getType());
|
|
||||||
klb.writeToStream(out);
|
|
||||||
out.flush();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,31 @@
|
|||||||
package org.kne.cloud.network.klalb;
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
import java.io.DataInput;
|
import java.io.DataInput;
|
||||||
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutput;
|
import java.io.DataOutput;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.EOFException;
|
||||||
import java.io.Externalizable;
|
import java.io.Externalizable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.ObjectInput;
|
import java.io.ObjectInput;
|
||||||
import java.io.ObjectOutput;
|
import java.io.ObjectOutput;
|
||||||
|
import java.io.StreamCorruptedException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.channels.Channels;
|
||||||
|
import java.nio.channels.ReadableByteChannel;
|
||||||
|
import java.nio.channels.WritableByteChannel;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
public abstract class KLALBPacket implements Sumable{
|
public abstract class KLALBPacket implements Comparable<KLALBPacket>{
|
||||||
public static final int PING=0;
|
public static final int PING=0;
|
||||||
public static final int PONG=1;
|
public static final int PONG=1;
|
||||||
public static final int SYNT=2;
|
public static final int BWINF=2;
|
||||||
public static final int SACKT=3;
|
//public static final int SYNT=2;
|
||||||
|
//public static final int SACKT=3;
|
||||||
public static final int RST=4;
|
public static final int RST=4;
|
||||||
public static final int DATAT=5;
|
public static final int DATAT=5;
|
||||||
public static final int ACKT=6;
|
public static final int ACKT=6;
|
||||||
@@ -23,26 +36,61 @@ public abstract class KLALBPacket implements Sumable{
|
|||||||
public static final int TEST=11;
|
public static final int TEST=11;
|
||||||
public static final int VADDRACK=12;
|
public static final int VADDRACK=12;
|
||||||
public static final int VADDRREQ=13;
|
public static final int VADDRREQ=13;
|
||||||
private int type;
|
|
||||||
|
|
||||||
|
private static final int HEADER_CAPACITY = 32;
|
||||||
|
public static final ByteBufferPool headerbufferpool=new ByteBufferPool(1000, HEADER_CAPACITY);
|
||||||
|
public static final ByteBufferPool databufferpool=new ByteBufferPool(1000, 65535);
|
||||||
|
|
||||||
|
//public static final ByteArrayPool dataarraypool=new ByteArrayPool(5000, 8192);
|
||||||
|
|
||||||
|
protected volatile ByteBuffer header;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
protected KLALBPacket(ByteBuffer header) {
|
||||||
|
super();
|
||||||
|
this.header = header;
|
||||||
|
}
|
||||||
|
|
||||||
public KLALBPacket(int type) {
|
public KLALBPacket(int type) {
|
||||||
super();
|
super();
|
||||||
this.type = type;
|
header=headerbufferpool.borrow();
|
||||||
|
header.put((byte) type);
|
||||||
|
}
|
||||||
|
public KLALBPacket(int type, long priority) {
|
||||||
|
this(type);
|
||||||
|
this.priority=priority;
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "KLALBPacket [type=" + type + "]";
|
return "KLALBPacket [type=" + getType() + "]";
|
||||||
}
|
}
|
||||||
public int getType() {
|
public int getType() {
|
||||||
return type;
|
return header.get(0)&0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
private long sndtime,rcvtime;
|
private long sndtime,rcvtime;
|
||||||
protected void writeToStream(DataOutput dto) throws IOException {
|
|
||||||
|
|
||||||
|
|
||||||
|
protected void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||||
sndtime=System.nanoTime();
|
sndtime=System.nanoTime();
|
||||||
|
dto.write(header.slice(0, getHeaderSize()));
|
||||||
}
|
}
|
||||||
protected void readFromStream(DataInput din) throws IOException {
|
|
||||||
|
protected void readFromChannel(ReadableByteChannel din) throws IOException {
|
||||||
rcvtime=System.nanoTime();
|
rcvtime=System.nanoTime();
|
||||||
|
header.limit(getHeaderSize());
|
||||||
|
while(header.hasRemaining()){
|
||||||
|
if(din.read(header)==-1) {
|
||||||
|
throw new EOFException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int getHeaderSize() {
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
public long getSndtime() {
|
public long getSndtime() {
|
||||||
return sndtime;
|
return sndtime;
|
||||||
@@ -51,19 +99,150 @@ public abstract class KLALBPacket implements Sumable{
|
|||||||
return rcvtime;
|
return rcvtime;
|
||||||
}
|
}
|
||||||
public long getLength() {
|
public long getLength() {
|
||||||
return 1;
|
return getHeaderSize();
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public long getValue() {
|
|
||||||
return getLength();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getPriority() {
|
||||||
|
return priority;
|
||||||
|
}
|
||||||
|
public void setPriority(long priority) {
|
||||||
|
this.priority = priority;
|
||||||
|
}
|
||||||
|
public long getSendseq() {
|
||||||
|
return sendseq;
|
||||||
|
}
|
||||||
|
|
||||||
|
private long priority;
|
||||||
|
private long sendseq;
|
||||||
|
private static final AtomicLong seqgen=new AtomicLong();
|
||||||
|
|
||||||
private Vector<KLALBRemoteLine> sendRecord=new Vector<>();
|
@Override
|
||||||
|
public int compareTo(KLALBPacket o) {
|
||||||
|
if(priority>o.priority) {
|
||||||
|
return 1;
|
||||||
|
}else if(priority<o.priority){
|
||||||
|
return -1;
|
||||||
|
}else {
|
||||||
|
if(sendseq>o.sendseq) {
|
||||||
|
return 1;
|
||||||
|
}else if(sendseq<o.sendseq){
|
||||||
|
return -1;
|
||||||
|
}else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected void genseq() {
|
||||||
|
this.sendseq=seqgen.getAndIncrement();
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<KLALBRemoteLine> sendRecord=new ArrayList<>(2);
|
||||||
|
private volatile boolean disposed;
|
||||||
|
private volatile ReentrantLock disposeLock=new ReentrantLock();
|
||||||
|
public boolean isDisposed() {
|
||||||
|
return disposed;
|
||||||
|
}
|
||||||
|
|
||||||
public Vector<KLALBRemoteLine> getSendRecord() {
|
public List<KLALBRemoteLine> getSendRecord() {
|
||||||
return sendRecord;
|
return sendRecord;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public ReentrantLock getDisposeLock() {
|
||||||
|
return disposeLock;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ByteBuffer getHeader() {
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void dispose() {
|
||||||
|
disposeLock.lock();
|
||||||
|
try {
|
||||||
|
disposed=true;
|
||||||
|
}finally {
|
||||||
|
disposeLock.unlock();
|
||||||
|
}
|
||||||
|
ByteBuffer headerx=header;
|
||||||
|
header=null;
|
||||||
|
KLALBPacket.headerbufferpool.back(headerx);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static KLALBPacket readKLALBPacketFromStream(DataInputStream in) throws IOException {
|
||||||
|
return readKLALBPacketFromChannel(Channels.newChannel(in));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static KLALBPacket readKLALBPacketFromChannel(ReadableByteChannel in) throws IOException {
|
||||||
|
ByteBuffer bb=headerbufferpool.borrow();
|
||||||
|
bb.limit(1);
|
||||||
|
while(bb.hasRemaining()){
|
||||||
|
if(in.read(bb)==-1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int type=bb.get(0);
|
||||||
|
bb.limit(bb.capacity());
|
||||||
|
|
||||||
|
KLALBPacket klp;
|
||||||
|
switch(type) {
|
||||||
|
case PING:klp=new PINGPacket(bb);
|
||||||
|
klp.readFromChannel(in);
|
||||||
|
return klp;
|
||||||
|
case PONG:
|
||||||
|
klp=new PONGPacket(bb);
|
||||||
|
klp.readFromChannel(in);
|
||||||
|
return klp;
|
||||||
|
case BWINF:
|
||||||
|
klp=new BWINFPacket(bb);
|
||||||
|
klp.readFromChannel(in);
|
||||||
|
return klp;
|
||||||
|
case RST:
|
||||||
|
klp=new RSTPacket(bb);
|
||||||
|
klp.readFromChannel(in);
|
||||||
|
return klp;
|
||||||
|
case DATAT:
|
||||||
|
klp=new DATATPacket(bb);
|
||||||
|
klp.readFromChannel(in);
|
||||||
|
return klp;
|
||||||
|
case ACKT:
|
||||||
|
klp=new ACKTPacket(bb);
|
||||||
|
klp.readFromChannel(in);
|
||||||
|
return klp;
|
||||||
|
case VADDR:
|
||||||
|
klp=new VADDRPacket(bb);
|
||||||
|
klp.readFromChannel(in);
|
||||||
|
return klp;
|
||||||
|
case ADDLINES:
|
||||||
|
klp=new ADDLINESPacket(bb);
|
||||||
|
klp.readFromChannel(in);
|
||||||
|
return klp;
|
||||||
|
case NACKT:
|
||||||
|
klp=new NACKTPacket(bb);
|
||||||
|
klp.readFromChannel(in);
|
||||||
|
return klp;
|
||||||
|
case TEST:
|
||||||
|
klp=new TESTPacket(bb);
|
||||||
|
klp.readFromChannel(in);
|
||||||
|
return klp;
|
||||||
|
case VADDRACK:
|
||||||
|
klp=new VADDRACKPacket(bb);
|
||||||
|
klp.readFromChannel(in);
|
||||||
|
return klp;
|
||||||
|
case VADDRREQ:
|
||||||
|
klp=new VADDRREQPacket(bb);
|
||||||
|
klp.readFromChannel(in);
|
||||||
|
return klp;
|
||||||
|
}
|
||||||
|
throw new StreamCorruptedException("unknown package type:"+type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void writeKLALBPacketToStream(DataOutputStream out,KLALBPacket klb) throws IOException {
|
||||||
|
writeKLALBPacketToChannel(Channels.newChannel(out),klb);
|
||||||
|
}
|
||||||
|
public static void writeKLALBPacketToChannel(WritableByteChannel writableByteChannel,KLALBPacket klb) throws IOException {
|
||||||
|
klb.writeToChannel(writableByteChannel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,9 +5,14 @@ import java.net.SocketException;
|
|||||||
|
|
||||||
public interface KLALBPacketLink {
|
public interface KLALBPacketLink {
|
||||||
public void writePacket(KLALBPacket kp) throws IOException;
|
public void writePacket(KLALBPacket kp) throws IOException;
|
||||||
|
public void flush() throws IOException;
|
||||||
public KLALBPacket readPacket()throws IOException;
|
public KLALBPacket readPacket()throws IOException;
|
||||||
public void close() throws IOException;
|
public void close() throws IOException;
|
||||||
public boolean isClosed();
|
public boolean isClosed();
|
||||||
public void setSoTimeout(int val) throws SocketException;
|
public void setSoTimeout(int val) throws SocketException;
|
||||||
public int getSoTimeout() throws SocketException;
|
public int getSoTimeout() throws SocketException;
|
||||||
|
@Override
|
||||||
|
public String toString();
|
||||||
|
public boolean isStream();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,303 @@
|
|||||||
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.net.Inet6Address;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.net.SocketException;
|
||||||
|
import java.net.SocketTimeoutException;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Hashtable;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import org.kne.cloud.network.*;
|
||||||
|
import org.kne.cloud.network.minecraft.MinecraftSocketBridge;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonParser;
|
||||||
|
import com.google.gson.JsonPrimitive;
|
||||||
|
|
||||||
|
public class KLALBProxySystem {
|
||||||
|
private Set<Proxy> proxys=new HashSet<>();
|
||||||
|
private KLALBController klalbController;
|
||||||
|
private KLALBRemoteManagement krm;
|
||||||
|
public Set<Proxy> getProxys() {
|
||||||
|
return proxys;
|
||||||
|
}
|
||||||
|
public KLALBController getKlalbController() {
|
||||||
|
return klalbController;
|
||||||
|
}
|
||||||
|
public KLALBProxySystem(Reader json) {
|
||||||
|
loadConfigJson(json);
|
||||||
|
}
|
||||||
|
public KLALBProxySystem(String json) {
|
||||||
|
loadConfigJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
public KLALBProxySystem(JsonElement json) {
|
||||||
|
loadConfigJson(json);
|
||||||
|
}
|
||||||
|
public KLALBProxySystem(File jsonFile) throws IOException {
|
||||||
|
loadConfigJson(jsonFile);
|
||||||
|
}
|
||||||
|
public KLALBProxySystem() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void enableRemoteManagement() throws IOException {
|
||||||
|
if(krm==null) {
|
||||||
|
krm=new KLALBRemoteManagement(this);
|
||||||
|
}else {
|
||||||
|
throw new IllegalStateException("Remote Management already enabled!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void enableRemoteManagement(MultipurposeSocketAddress bind) throws IOException {
|
||||||
|
if(krm==null) {
|
||||||
|
krm=new KLALBRemoteManagement(this,bind);
|
||||||
|
}else {
|
||||||
|
throw new IllegalStateException("Remote Management already enabled!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRemoteManagementEnabled() {
|
||||||
|
return krm!=null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void disableRemoteManagement() {
|
||||||
|
if(krm!=null) {
|
||||||
|
krm.close();
|
||||||
|
krm=null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadConfigJson(File jsonFile) throws IOException {
|
||||||
|
FileReader fr = null;
|
||||||
|
try {
|
||||||
|
fr=new FileReader(jsonFile);
|
||||||
|
loadConfigJson(fr);
|
||||||
|
}finally {
|
||||||
|
if(fr!=null)
|
||||||
|
fr.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public void loadConfigJson(String json) {
|
||||||
|
loadConfigJson(new JsonParser().parse(json));
|
||||||
|
}
|
||||||
|
public void loadConfigJson(Reader json) {
|
||||||
|
loadConfigJson(new JsonParser().parse(json));
|
||||||
|
}
|
||||||
|
public void loadConfigJson(JsonElement json) {
|
||||||
|
JsonArray jobj=(JsonArray) json;
|
||||||
|
jobj.forEach((val)->{
|
||||||
|
solveEntry((JsonObject) val);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
protected void solveEntry(JsonObject entry){
|
||||||
|
switch (entry.get("Type").getAsString()) {
|
||||||
|
case "KLALBController":
|
||||||
|
JsonElement vase= entry.get("VirtualAddress");
|
||||||
|
if(vase!=null) {
|
||||||
|
try {
|
||||||
|
klalbController=new KLALBController((Inet6Address) InetAddress.getByName(vase.getAsString()));
|
||||||
|
} catch (UnknownHostException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
klalbController=new KLALBController();
|
||||||
|
}
|
||||||
|
JsonElement vsne=entry.get("VirtualSocketName");
|
||||||
|
//if(vsne!=null) {
|
||||||
|
MultipurposeSocketAddress.getSocketTypeRegister().put(vsne.getAsString(), klalbController.getSocketType());
|
||||||
|
//}
|
||||||
|
JsonElement tcple=entry.get("TCPListen");
|
||||||
|
if(tcple!=null) {
|
||||||
|
MultipurposeSocketAddress mpsa=new MultipurposeSocketAddress(tcple.getAsString());
|
||||||
|
|
||||||
|
SocketChannelListener tcpl = null;
|
||||||
|
try {
|
||||||
|
tcpl = new SocketChannelListener(mpsa);
|
||||||
|
|
||||||
|
tcpl.setCon((soc)->{
|
||||||
|
|
||||||
|
KLALBRemoteLine krs=null;
|
||||||
|
try {
|
||||||
|
krs = new KLALBRemoteLine(new StreamChannelKLALBPacketLink(soc));
|
||||||
|
klalbController.addRemoteLine(krs);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
klalbController.getListenSocketAddress().add(mpsa);
|
||||||
|
} catch (IOException e1) {
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JsonElement udple=entry.get("UDPListen");
|
||||||
|
if(udple!=null) {
|
||||||
|
MultipurposeSocketAddress mpsa=new MultipurposeSocketAddress(udple.getAsString());
|
||||||
|
DatagramSocketListener udpl = null;
|
||||||
|
try {
|
||||||
|
udpl = new DatagramSocketListener(mpsa);
|
||||||
|
|
||||||
|
udpl.setCon((soc)->{
|
||||||
|
|
||||||
|
KLALBRemoteLine krs=null;
|
||||||
|
try {
|
||||||
|
krs = new KLALBRemoteLine(new SplitedDatagramKLALBPacketLink(soc));
|
||||||
|
klalbController.addRemoteLine(krs);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
//klalbController.getListenSocketAddress().add(mpsa);
|
||||||
|
} catch (IOException e1) {
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JsonElement linele=entry.get("LineTable");
|
||||||
|
if(linele!=null) {
|
||||||
|
JsonArray jary=(JsonArray)linele;
|
||||||
|
jary.forEach((aline)->{
|
||||||
|
klalbController.getSelflineTable().add(new MultipurposeSocketAddress(aline.getAsString()));
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
JsonElement linetoc=entry.get("ConnectLineTable");
|
||||||
|
if(linetoc!=null) {
|
||||||
|
JsonArray jary=(JsonArray)linetoc;
|
||||||
|
jary.forEach((aline)->{
|
||||||
|
try {
|
||||||
|
klalbController.addRemoteLines(new MultipurposeSocketAddress(aline.getAsString()));
|
||||||
|
} catch (SocketTimeoutException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (SocketException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "SocketBridge":
|
||||||
|
|
||||||
|
try {
|
||||||
|
proxys.add(createProxyByJson(entry));
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public Proxy createProxyByJson(JsonObject entry) throws IOException {
|
||||||
|
HostPortMap mapp=new HostPortMap();
|
||||||
|
LinkedHashMap<String, SocketBridgeFactory>mapb=new LinkedHashMap<>();
|
||||||
|
MultipurposeSocketAddress l=new MultipurposeSocketAddress(entry.get("Listen").getAsString());
|
||||||
|
SocketBridgeFactory bdg=getDefaultBridgeFactory(entry.get("Bridge"),mapb);
|
||||||
|
MultipurposeSocketAddress r=getDefaultConnect(entry.get("Connect"),mapp);
|
||||||
|
return new SocketToSocketProxy(l ,new MultipurposeSocketAddress("0.0.0.0:0"), r,mapp,bdg,mapb);
|
||||||
|
}
|
||||||
|
public JsonObject createJsonObjectByProxy(Proxy p) {
|
||||||
|
if(p instanceof SocketToSocketProxy) {
|
||||||
|
SocketToSocketProxy stsp=(SocketToSocketProxy) p;
|
||||||
|
JsonObject jobj=new JsonObject();
|
||||||
|
jobj.addProperty("Listen", stsp.getListen().toString());
|
||||||
|
jobj.add("Bridge", getJsonElementByBridges(stsp));
|
||||||
|
jobj.add("Connect", getJsonElementByConnects(stsp));
|
||||||
|
return jobj;
|
||||||
|
}else {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private JsonElement getJsonElementByConnects(SocketToSocketProxy stsp) {
|
||||||
|
if(stsp.getDetectedConnect()==null||stsp.getDetectedConnect().isEmpty()) {
|
||||||
|
return new JsonPrimitive(stsp.getDefaultConnect().toString());
|
||||||
|
}else {
|
||||||
|
JsonObject jo=new JsonObject();
|
||||||
|
for (Iterator<Entry<String, MultipurposeSocketAddress>> iterator = stsp.getDetectedConnect().entrySet().iterator(); iterator.hasNext();) {
|
||||||
|
Entry<String, MultipurposeSocketAddress> proxy = (Entry<String, MultipurposeSocketAddress>) iterator.next();
|
||||||
|
if(!proxy.getKey().equals("DEFAULT")) {
|
||||||
|
jo.addProperty(proxy.getKey(), proxy.getValue().toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jo.addProperty("DEFAULT", stsp.getDefaultConnect().toString());
|
||||||
|
return jo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private JsonElement getJsonElementByBridges(SocketToSocketProxy stsp) {
|
||||||
|
if(stsp.getDetectedFactory()==null||stsp.getDetectedFactory().isEmpty()) {
|
||||||
|
return new JsonPrimitive(getJobjByFActory(stsp.getDefaultFactory()));
|
||||||
|
}else {
|
||||||
|
JsonObject jo=new JsonObject();
|
||||||
|
for (Iterator<Entry<String, SocketBridgeFactory>> iterator = stsp.getDetectedFactory().entrySet().iterator(); iterator.hasNext();) {
|
||||||
|
Entry<String, SocketBridgeFactory> proxy = (Entry<String, SocketBridgeFactory>) iterator.next();
|
||||||
|
if(!proxy.getKey().equals("DEFAULT")) {
|
||||||
|
jo.addProperty(proxy.getKey(), getJobjByFActory(proxy.getValue()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jo.addProperty("DEFAULT",getJobjByFActory( stsp.getDefaultFactory()));
|
||||||
|
return jo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private MultipurposeSocketAddress getDefaultConnect(JsonElement jsonElement, LinkedHashMap<String, MultipurposeSocketAddress> mapp) {
|
||||||
|
if(jsonElement instanceof JsonObject) {
|
||||||
|
JsonObject jobj=(JsonObject) jsonElement;
|
||||||
|
jobj.entrySet().forEach((en)->{
|
||||||
|
mapp.put(en.getKey(), new MultipurposeSocketAddress( en.getValue().getAsString()));
|
||||||
|
});
|
||||||
|
return mapp.get("DEFAULT");
|
||||||
|
}else {
|
||||||
|
return new MultipurposeSocketAddress(jsonElement.getAsString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private SocketBridgeFactory getDefaultBridgeFactory(JsonElement jsonElement, LinkedHashMap<String, SocketBridgeFactory> mapp) {
|
||||||
|
if(jsonElement instanceof JsonObject) {
|
||||||
|
JsonObject jobj=(JsonObject) jsonElement;
|
||||||
|
jobj.entrySet().forEach((en)->{
|
||||||
|
mapp.put(en.getKey(), getFactoryByJobj(en.getValue().getAsString()));
|
||||||
|
});
|
||||||
|
return mapp.get("DEFAULT");
|
||||||
|
}else {
|
||||||
|
return getFactoryByJobj(jsonElement.getAsString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private SocketBridgeFactory getFactoryByJobj(String string) {
|
||||||
|
if(string.startsWith("SocketBridge")) {
|
||||||
|
return new DefaultSocketBridgeFactory();
|
||||||
|
}else if(string.startsWith("MinecraftSocketBridge")) {
|
||||||
|
return new DefaultMinecraftSocketBridgeFactory(klalbController.getSelf(), Integer.parseInt(string.substring(21)));
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("unknown SocketBridge type:"+string);
|
||||||
|
}
|
||||||
|
private String getJobjByFActory(SocketBridgeFactory sbf) {
|
||||||
|
if(sbf instanceof DefaultSocketBridgeFactory) {
|
||||||
|
return "SocketBridge";
|
||||||
|
}else if(sbf instanceof DefaultMinecraftSocketBridgeFactory) {
|
||||||
|
return "MinecraftSocketBridge"+((DefaultMinecraftSocketBridgeFactory)sbf).getVport();
|
||||||
|
}else {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private KLALBStateGUI2 kgui;
|
||||||
|
public KLALBStateGUI2 getKLALBGUI() {
|
||||||
|
if(kgui==null)
|
||||||
|
kgui=new KLALBStateGUI2(klalbController);
|
||||||
|
return kgui;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
package org.kne.cloud.network.klalb;
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
@@ -10,30 +12,62 @@ import java.net.InetAddress;
|
|||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.net.SocketTimeoutException;
|
import java.net.SocketTimeoutException;
|
||||||
|
import java.nio.channels.UnresolvedAddressException;
|
||||||
|
import java.time.Clock;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.PriorityQueue;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.PriorityBlockingQueue;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.concurrent.locks.LockSupport;
|
import java.util.concurrent.locks.LockSupport;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import javax.management.monitor.Monitor;
|
||||||
|
|
||||||
|
import org.kne.cloud.clock.AdjustedNanoClock;
|
||||||
|
import org.kne.cloud.clock.ExponentialBackoffTimeClock;
|
||||||
|
import org.kne.cloud.clock.ReliabilityBackoffTimeClock;
|
||||||
import org.kne.cloud.network.MultipurposeSocketAddress;
|
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||||
|
import org.kne.cloud.network.SpeedLimiter;
|
||||||
import org.kne.cloud.network.ThreadTool;
|
import org.kne.cloud.network.ThreadTool;
|
||||||
|
import org.kne.cloud.network.monitor.MonitorData;
|
||||||
|
import org.kne.cloud.network.monitor.SpeedAndTrafficAndDelayMonitorDataImpl;
|
||||||
|
import org.kne.cloud.network.monitor.SpeedAndTrafficMonitorDataImpl;
|
||||||
|
import org.kne.debug.TimeDebugger;
|
||||||
|
|
||||||
public class KLALBRemoteLine implements Comparable<KLALBRemoteLine>{
|
public class KLALBRemoteLine implements Comparable<KLALBRemoteLine> {
|
||||||
|
|
||||||
|
private static final boolean debug = true;
|
||||||
|
|
||||||
|
private static final boolean showpacket = false;
|
||||||
|
|
||||||
|
private ReliabilityBackoffTimeClock coll = new ReliabilityBackoffTimeClock();
|
||||||
|
private volatile boolean closed = false;
|
||||||
|
|
||||||
private volatile boolean closed=false;
|
|
||||||
|
|
||||||
private volatile Supplier<Inet6Address> localVaddrSupplier;
|
private volatile Supplier<Inet6Address> localVaddrSupplier;
|
||||||
|
|
||||||
|
private volatile KLALBController klalbController;
|
||||||
|
|
||||||
|
public KLALBController getKlalbController() {
|
||||||
|
return klalbController;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKlalbController(KLALBController klalbController) {
|
||||||
|
this.klalbController = klalbController;
|
||||||
|
if (klalbController != null && remoteVaddr != null) {
|
||||||
|
adjnc = klalbController.getAdjustedClockByVaddr(remoteVaddr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Supplier<Inet6Address> getLocalVaddrSupplier() {
|
public Supplier<Inet6Address> getLocalVaddrSupplier() {
|
||||||
return localVaddrSupplier;
|
return localVaddrSupplier;
|
||||||
}
|
}
|
||||||
@@ -41,45 +75,44 @@ public class KLALBRemoteLine implements Comparable<KLALBRemoteLine>{
|
|||||||
public void setLocalVaddrSupplier(Supplier<Inet6Address> localVaddrSupplier) {
|
public void setLocalVaddrSupplier(Supplier<Inet6Address> localVaddrSupplier) {
|
||||||
this.localVaddrSupplier = localVaddrSupplier;
|
this.localVaddrSupplier = localVaddrSupplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private volatile Inet6Address remoteVaddr;
|
private volatile Inet6Address remoteVaddr;
|
||||||
public Inet6Address getRemoteVaddr() throws SocketTimeoutException {
|
|
||||||
|
public Inet6Address getRemoteVaddr() {
|
||||||
return remoteVaddr;
|
return remoteVaddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private volatile AdjustedNanoClock adjnc = new AdjustedNanoClock();
|
||||||
|
|
||||||
public void waitForRemoteVaddrAvaliable(long timeout) throws SocketTimeoutException {
|
public void waitForRemoteVaddrAvaliable(long timeout) throws SocketTimeoutException {
|
||||||
long s=System.nanoTime();
|
long s = System.nanoTime();
|
||||||
while(remoteVaddr==null) {
|
while (remoteVaddr == null) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Thread.sleep(1);
|
Thread.sleep(1);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
if(System.nanoTime()-s>timeout*1000000)
|
if (System.nanoTime() - s > timeout * 1000000)
|
||||||
throw new SocketTimeoutException();
|
throw new SocketTimeoutException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Monitor getMonitor() {
|
public SpeedAndTrafficAndDelayMonitorDataImpl getMonitor() {
|
||||||
return monitor;
|
return monitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return remoteVaddr+"\t"+monitor.toString()+"\t"+sumNextPacketCount();
|
return remoteVaddr + "\t" + monitor.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString2() {
|
private SpeedAndTrafficAndDelayMonitorDataImpl monitor;
|
||||||
return remoteVaddr+"\t"+monitor.toString2();
|
|
||||||
}
|
|
||||||
private Monitor monitor;
|
|
||||||
private volatile KLALBPacketLink kplink;
|
private volatile KLALBPacketLink kplink;
|
||||||
private MultipurposeSocketAddress bindAddress;
|
private MultipurposeSocketAddress bindAddress;
|
||||||
private MultipurposeSocketAddress socketAddress;
|
private MultipurposeSocketAddress socketAddress;
|
||||||
|
|
||||||
private Thread lthd;
|
private Thread lthd;
|
||||||
|
|
||||||
|
|
||||||
public void setKplink(KLALBPacketLink kplink) {
|
public void setKplink(KLALBPacketLink kplink) {
|
||||||
this.kplink = kplink;
|
this.kplink = kplink;
|
||||||
}
|
}
|
||||||
@@ -88,415 +121,554 @@ public class KLALBRemoteLine implements Comparable<KLALBRemoteLine>{
|
|||||||
return kplink;
|
return kplink;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public MultipurposeSocketAddress getSocketAddress() {
|
public MultipurposeSocketAddress getSocketAddress() {
|
||||||
return socketAddress;
|
return socketAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public MultipurposeSocketAddress getBindAddress() {
|
public MultipurposeSocketAddress getBindAddress() {
|
||||||
return bindAddress;
|
return bindAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static KLALBPacketLink createLink(MultipurposeSocketAddress bindAddress,MultipurposeSocketAddress mpa) throws IOException {
|
protected static KLALBPacketLink createLink(MultipurposeSocketAddress bindAddress, MultipurposeSocketAddress mpa)
|
||||||
if(mpa.isStream()) {
|
throws IOException {
|
||||||
if(bindAddress!=null) {
|
if (mpa.isStream()) {
|
||||||
return new StreamKLALBPacketLink(mpa.connectSocket(InetAddress.getByName( bindAddress.getHost()),bindAddress.getPort()));
|
if (mpa.supportNIO()) {
|
||||||
}else {
|
if (bindAddress != null) {
|
||||||
return new StreamKLALBPacketLink(mpa.connectSocket());
|
return new StreamChannelKLALBPacketLink(mpa
|
||||||
|
.connectSocketChannel(InetAddress.getByName(bindAddress.getHost()), bindAddress.getPort()));
|
||||||
|
} else {
|
||||||
|
return new StreamChannelKLALBPacketLink(mpa.connectSocketChannel());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (bindAddress != null) {
|
||||||
|
return new StreamKLALBPacketLink(
|
||||||
|
mpa.connectSocket(InetAddress.getByName(bindAddress.getHost()), bindAddress.getPort()));
|
||||||
|
} else {
|
||||||
|
return new StreamKLALBPacketLink(mpa.connectSocket());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (bindAddress != null) {
|
||||||
|
return new SplitedDatagramKLALBPacketLink(
|
||||||
|
mpa.connectDatagramSocket(InetAddress.getByName(bindAddress.getHost()), bindAddress.getPort()));
|
||||||
|
} else {
|
||||||
|
return new SplitedDatagramKLALBPacketLink(mpa.connectDatagramSocket());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
if(bindAddress!=null) {
|
|
||||||
return new DatagramKLALBPacketLink(mpa.connectDatagramSocket(InetAddress.getByName( bindAddress.getHost()),bindAddress.getPort()));
|
|
||||||
}else {
|
|
||||||
return new DatagramKLALBPacketLink(mpa.connectDatagramSocket());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public KLALBRemoteLine(MultipurposeSocketAddress mpa) {
|
|
||||||
this(mpa,new Monitor());
|
|
||||||
}
|
|
||||||
public KLALBRemoteLine(MultipurposeSocketAddress mpa,Monitor monitor) {
|
|
||||||
this(mpa,null,monitor);
|
|
||||||
}
|
|
||||||
public KLALBRemoteLine(KLALBPacketLink kpl) {
|
|
||||||
this(kpl,new Monitor());
|
|
||||||
}
|
|
||||||
public KLALBRemoteLine(KLALBPacketLink kpl,Monitor monitor) {
|
|
||||||
this.kplink=kpl;
|
|
||||||
this.monitor=monitor;
|
|
||||||
monitor.setName(kpl.toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public KLALBRemoteLine(MultipurposeSocketAddress mpa,MultipurposeSocketAddress bindaddr,Monitor monitor ) {
|
public KLALBRemoteLine(MultipurposeSocketAddress mpa) {
|
||||||
this.socketAddress=mpa;
|
this(mpa, new SpeedAndTrafficAndDelayMonitorDataImpl());
|
||||||
this.bindAddress=bindaddr;
|
}
|
||||||
this.monitor=monitor;
|
|
||||||
monitor.setName(mpa.toString());
|
public KLALBRemoteLine(MultipurposeSocketAddress mpa, SpeedAndTrafficAndDelayMonitorDataImpl monitor) {
|
||||||
|
this(mpa, null, monitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public KLALBRemoteLine(KLALBPacketLink kpl) {
|
||||||
|
this(kpl, new SpeedAndTrafficAndDelayMonitorDataImpl());
|
||||||
|
}
|
||||||
|
|
||||||
|
public KLALBRemoteLine(KLALBPacketLink kpl, SpeedAndTrafficAndDelayMonitorDataImpl monitor) {
|
||||||
|
this.kplink = kpl;
|
||||||
|
this.monitor = monitor;
|
||||||
|
monitor.setName(kpl.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public KLALBRemoteLine(MultipurposeSocketAddress mpa, MultipurposeSocketAddress bindaddr,
|
||||||
|
SpeedAndTrafficAndDelayMonitorDataImpl monitor) {
|
||||||
|
this.socketAddress = mpa;
|
||||||
|
this.bindAddress = bindaddr;
|
||||||
|
this.monitor = monitor;
|
||||||
|
if (bindaddr == null) {
|
||||||
|
monitor.setName("→" + mpa.toString());
|
||||||
|
} else {
|
||||||
|
monitor.setName(bindaddr.toString() + "→" + mpa.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public KLALBRemoteLine(MultipurposeSocketAddress mpa, MultipurposeSocketAddress bindaddr) {
|
public KLALBRemoteLine(MultipurposeSocketAddress mpa, MultipurposeSocketAddress bindaddr) {
|
||||||
this(mpa,bindaddr,new Monitor());
|
this(mpa, bindaddr, new SpeedAndTrafficAndDelayMonitorDataImpl());
|
||||||
}
|
}
|
||||||
PrintStream pw;
|
|
||||||
private void startRecord() {
|
|
||||||
try {
|
|
||||||
pw=new PrintStream(UUID.randomUUID()+".csv");
|
|
||||||
|
|
||||||
pw.println("时间,状态,上传速度,下载速度,上传延迟,下载延迟,往返延迟,抖动");
|
PrintStream pw;
|
||||||
ThreadTool.makePDaemonThreadIfSupport("BigData Record", ()->{
|
|
||||||
while(true) {
|
private boolean flag=false;
|
||||||
|
private void startRecord() {
|
||||||
|
if(flag)
|
||||||
|
return;
|
||||||
|
flag=true;
|
||||||
|
try {
|
||||||
|
File fl = new File("logs");
|
||||||
|
if (!fl.exists()) {
|
||||||
|
fl.mkdirs();
|
||||||
|
}
|
||||||
|
File fx = new File(fl, getMonitor().getName().replace(':', ':') + ".csv");
|
||||||
|
pw = new PrintStream(new FileOutputStream(fx, true));
|
||||||
|
|
||||||
|
if (fx.length() <= 0)
|
||||||
|
pw.println("时间,状态,上传速度,下载速度,上传延迟,下载延迟,往返延迟,抖动");
|
||||||
|
ThreadTool.makeVDaemonThreadIfSupport("BigData Record", () -> {
|
||||||
|
while (!closed) {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(1000);
|
Thread.sleep(100);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
pw.println(System.currentTimeMillis()+","+monitor.getState()+","+monitor.getOutSpeedAvg()+","+monitor.getInSpeedAvg()+","+sndDelayFactor+","+rcvDelayFactor+","+monitor.getLatencyAvg()+","+monitor.getJitter());
|
pw.println(System.currentTimeMillis() + "," + monitor.getState() + "," + monitor.getOutSpeed() + ","
|
||||||
|
+ monitor.getInSpeed() + "," + monitor.getOutDelay() + "," + monitor.getInDelay() + ","
|
||||||
|
+ monitor.getLatency() + "," + monitor.getTotalJitter());
|
||||||
}
|
}
|
||||||
|
pw.close();
|
||||||
}).start();
|
}).start();
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void endRecord() {
|
|
||||||
if(pw!=null)
|
|
||||||
pw.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void startIO() {
|
|
||||||
ThreadTool.makePDaemonThreadIfSupport("远程接收线程", () -> {
|
|
||||||
//startRecord();
|
|
||||||
while(true) {
|
|
||||||
try {
|
|
||||||
|
|
||||||
monitor.setState(Monitor.CONNECTING);
|
private SpeedLimiter congress = new SpeedLimiter();
|
||||||
if(socketAddress==null) {
|
private long congressSpeed = 0;
|
||||||
if(kplink.isClosed()) {
|
private double increaceFactor = 1.2;
|
||||||
monitor.setState(Monitor.OFFLINE);
|
|
||||||
closed=true;
|
protected void startIO() {
|
||||||
break;
|
ThreadTool.makeVDaemonThreadIfSupport("远程接收线程", () -> {
|
||||||
}
|
while (true) {
|
||||||
}else {
|
|
||||||
try {
|
|
||||||
kplink=createLink(bindAddress,socketAddress);
|
|
||||||
}catch(BindException be){
|
|
||||||
//be.printStackTrace();
|
|
||||||
close();
|
|
||||||
throw be;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
kplink.setSoTimeout(10000);
|
|
||||||
Thread t=ThreadTool.makePDaemonThreadIfSupport("远程发送线程", () -> {
|
|
||||||
try {
|
try {
|
||||||
writePacketToKPL(new VADDRREQPacket());
|
|
||||||
writePacketToKPL(new VADDRREQPacket());
|
monitor.setState(MonitorData.CONNECTING);
|
||||||
writePacketToKPL(new VADDRREQPacket());
|
if (socketAddress == null) {
|
||||||
while ((!kplink.isClosed())&&(!closed)) {
|
if (kplink.isClosed()) {
|
||||||
if(checkPingTime()) {
|
close();
|
||||||
writePacketToKPL(new PINGPacket(System.nanoTime()));
|
break;
|
||||||
}else {
|
|
||||||
KLALBPacket kpp=getNextPacket();
|
|
||||||
long lth=statLengthBefore(10);
|
|
||||||
if(lth>65536*2) {
|
|
||||||
monitor.updateOutSpeedMax();
|
|
||||||
}
|
|
||||||
if(kpp!=null) {
|
|
||||||
pingInterval= 100000000L;
|
|
||||||
writePacketToKPL(kpp);
|
|
||||||
}else {
|
|
||||||
pingInterval=1000000000L;
|
|
||||||
tlock=Thread.currentThread();
|
|
||||||
LockSupport.parkNanos(1000000);
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
kplink = createLink(bindAddress, socketAddress);
|
||||||
|
}
|
||||||
|
startRecord();
|
||||||
|
kplink.setSoTimeout(10000);
|
||||||
|
Thread t = ThreadTool.makeVDaemonThreadIfSupport("远程发送线程", () -> {
|
||||||
|
try {
|
||||||
|
writePacketToKPL(new VADDRREQPacket());
|
||||||
|
writePacketToKPL(new VADDRREQPacket());
|
||||||
|
writePacketToKPL(new VADDRPacket(localVaddrSupplier.get()));
|
||||||
|
writePacketToKPL(new VADDRPacket(localVaddrSupplier.get()));
|
||||||
|
flushKPL();
|
||||||
|
KLALBPacket kpp = null;
|
||||||
|
while ((!kplink.isClosed()) && (!closed)) {
|
||||||
|
// TimeDebugger tdb=new TimeDebugger();
|
||||||
|
// tdb.putTime("start");
|
||||||
|
|
||||||
|
boolean flsh = false;
|
||||||
|
if (checkPingTime()) {
|
||||||
|
writePacketToKPL(new PINGPacket(System.nanoTime()));
|
||||||
|
if (remoteVaddr == null)
|
||||||
|
writePacketToKPL(new VADDRREQPacket());
|
||||||
|
monitor.updateSpeedSync();
|
||||||
|
flsh = true;
|
||||||
|
}
|
||||||
|
KLALBPacket kpip = IsendDequeList.poll();
|
||||||
|
if (kpip != null) {
|
||||||
|
writePacketToKPL(kpip);
|
||||||
|
flsh = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// tdb.putTime("Isend");
|
||||||
|
|
||||||
|
if (kpp == null) {
|
||||||
|
do {
|
||||||
|
kpp = sendDequeList.poll();
|
||||||
|
} while (kpp != null && kpp.isDisposed());
|
||||||
|
}
|
||||||
|
// System.out.println(sendDequeList.size());
|
||||||
|
if (kpp != null) {
|
||||||
|
kpp.getDisposeLock().lock();
|
||||||
|
try {
|
||||||
|
if (kpp.isDisposed()) {
|
||||||
|
kpp.getDisposeLock().unlock();
|
||||||
|
kpp = null;
|
||||||
|
} else {
|
||||||
|
if (congress.checkTransmit(kpp.getLength())) {
|
||||||
|
|
||||||
|
writePacketToKPL(kpp);
|
||||||
|
if (kpp instanceof DATATPacket) {
|
||||||
|
resetSleepTimer();
|
||||||
|
}
|
||||||
|
flsh = true;
|
||||||
|
kpp.getDisposeLock().unlock();
|
||||||
|
kpp = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if(kpp!=null)
|
||||||
|
kpp.getDisposeLock().unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (flsh) {
|
||||||
|
flushKPL();
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// tdb.putTime("send");
|
||||||
|
|
||||||
|
// tdb.putTime("flush");
|
||||||
|
|
||||||
|
if (pressure && pressureSpeed.checkTransmit(testPacket.getLength())) {
|
||||||
|
writePacketToKPL(testPacket);
|
||||||
|
flushKPL();
|
||||||
|
} else {
|
||||||
|
tlock = Thread.currentThread();
|
||||||
|
LockSupport.parkNanos(1000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// tdb.putTime("park");
|
||||||
|
}
|
||||||
|
|
||||||
|
// tdb.print();
|
||||||
|
// System.out.println(sendDequeList.isEmpty());
|
||||||
|
Thread.yield();
|
||||||
|
}
|
||||||
|
} catch (IOException | UnresolvedAddressException e) {
|
||||||
|
if (debug)
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
kplink.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
t.start();
|
||||||
|
boolean fst = true;
|
||||||
|
long stime = 5000000000L;
|
||||||
|
while ((!kplink.isClosed()) && (!closed)) {
|
||||||
|
long readStart = System.nanoTime();
|
||||||
|
KLALBPacket kpp = readPacketFromKPL();
|
||||||
|
long readTime = System.nanoTime() - readStart;
|
||||||
|
readTime *= 10;
|
||||||
|
if (readTime > stime) {
|
||||||
|
stime = readTime;
|
||||||
|
} else {
|
||||||
|
stime = (stime * 99 + readTime) / 100;
|
||||||
|
}
|
||||||
|
if (stime < 2000000000L) {
|
||||||
|
stime = 2000000000L;
|
||||||
|
}
|
||||||
|
|
||||||
|
// System.out.println(readTime);
|
||||||
|
// kplink.setSoTimeout(5000);
|
||||||
|
kplink.setSoTimeout((int) (stime / 1000000));
|
||||||
|
if (kpp == null)
|
||||||
|
break;
|
||||||
|
switch (kpp.getType()) {
|
||||||
|
case KLALBPacket.PING:
|
||||||
|
sendIPacket(new PONGPacket(((PINGPacket) kpp).getTime() ,kpp.getRcvtime(), System.nanoTime()));
|
||||||
|
sendIPacket(new BWINFPacket(monitor.getOutSpeed(), monitor.getInSpeed()));
|
||||||
|
break;
|
||||||
|
case KLALBPacket.PONG:
|
||||||
|
PONGPacket png = (PONGPacket) kpp;
|
||||||
|
long ul = png.getRcvtime() - png.getTimepingsnd()-(png.getTimepongsnd()-png.getTimepingrcv());
|
||||||
|
|
||||||
|
long DsndDelayFactor0 = png.getTimepingrcv() - png.getTimepingsnd();
|
||||||
|
long DrcvDelayFactor0 = png.getRcvtime() - png.getTimepongsnd();
|
||||||
|
long DsndDelayFactor;
|
||||||
|
long DrcvDelayFactor;
|
||||||
|
|
||||||
|
adjnc.getLock().lock();
|
||||||
|
try {
|
||||||
|
adjnc.calibrate(png.getTimepongsnd() + ul / 2 - png.getRcvtime(), ul / 2);
|
||||||
|
DsndDelayFactor = DsndDelayFactor0 - adjnc.getDelta();
|
||||||
|
DrcvDelayFactor = DrcvDelayFactor0 + adjnc.getDelta();
|
||||||
|
if (DsndDelayFactor < 0) {
|
||||||
|
if (DrcvDelayFactor < 0) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
adjnc.setDelta(adjnc.getDelta() + DsndDelayFactor);
|
||||||
|
DsndDelayFactor = DsndDelayFactor0 - adjnc.getDelta();
|
||||||
|
DrcvDelayFactor = DrcvDelayFactor0 + adjnc.getDelta();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (DrcvDelayFactor < 0) {
|
||||||
|
adjnc.setDelta(adjnc.getDelta() - DrcvDelayFactor);
|
||||||
|
DsndDelayFactor = DsndDelayFactor0 - adjnc.getDelta();
|
||||||
|
DrcvDelayFactor = DrcvDelayFactor0 + adjnc.getDelta();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
adjnc.getLock().unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DsndDelayFactor >= 0 && DrcvDelayFactor >= 0) {
|
||||||
|
monitor.setOutDelay(DsndDelayFactor);
|
||||||
|
monitor.setInDelay(DrcvDelayFactor);
|
||||||
|
monitor.setRecentPingNanoTime(png.getTimepingsnd());
|
||||||
|
pingInterval = monitor.getOutDelayMin();
|
||||||
|
|
||||||
|
double load = 1 - monitor.getOutDelayMin() / (double) monitor.getOutDelay();
|
||||||
|
increaceFactor =Math.max( 2.0 - load*2,1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
LockSupport.unpark(tlock);
|
||||||
|
break;
|
||||||
|
case KLALBPacket.BWINF:
|
||||||
|
BWINFPacket bwi = (BWINFPacket) kpp;
|
||||||
|
if (bwi.getDownSpeed() >= congressSpeed) {
|
||||||
|
congressSpeed = bwi.getDownSpeed();
|
||||||
|
} else {
|
||||||
|
congressSpeed = (congressSpeed * 999 + bwi.getDownSpeed()) / 1000;
|
||||||
|
}
|
||||||
|
congress.setLimitspeed((long) (congressSpeed * increaceFactor) + 32768);
|
||||||
|
// System.out.println(congressSpeed);
|
||||||
|
break;
|
||||||
|
case KLALBPacket.VADDRREQ:
|
||||||
|
sendIPacket(new VADDRPacket(localVaddrSupplier.get()));
|
||||||
|
break;
|
||||||
|
case KLALBPacket.VADDR:
|
||||||
|
Inet6Address vdr = ((VADDRPacket) kpp).getVaddr();
|
||||||
|
|
||||||
|
remoteVaddr = vdr;
|
||||||
|
sendIPacket(new VADDRACKPacket());
|
||||||
|
if (klalbController != null) {
|
||||||
|
adjnc = klalbController.getAdjustedClockByVaddr(remoteVaddr);
|
||||||
|
}
|
||||||
|
if (fst) {
|
||||||
|
// coll.resetCoolingTime();
|
||||||
|
monitor.setState(MonitorData.ONLINE);
|
||||||
|
fst = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KLALBPacket.VADDRACK:
|
||||||
|
break;
|
||||||
|
case KLALBPacket.TEST:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
while (rec == null) {
|
||||||
|
Thread.sleep(1);
|
||||||
|
}
|
||||||
|
rec.accept(KLALBRemoteLine.this, kpp);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
Thread.yield();
|
Thread.yield();
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException | UnresolvedAddressException e) {
|
||||||
|
if (debug)
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} finally {
|
} finally {
|
||||||
|
monitor.setState(MonitorData.OFFLINE);
|
||||||
|
pressure = false;
|
||||||
try {
|
try {
|
||||||
kplink.close();
|
if (kplink != null)
|
||||||
|
kplink.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
KLALBPacket pack;
|
||||||
});
|
while((pack=sendDequeList.poll())!=null) {
|
||||||
t.start();
|
try {
|
||||||
boolean fst=true;
|
if(remoteVaddr!=null) {
|
||||||
long stime=5000000000L;
|
klalbController.sendPacketToAddress(remoteVaddr, pack);
|
||||||
while ((!kplink.isClosed())&&(!closed)) {
|
if(debug)
|
||||||
long readStart=System.nanoTime();
|
System.out.println("RETRY:"+pack);
|
||||||
KLALBPacket kpp = readPacketFromKPL();
|
|
||||||
long readTime=System.nanoTime()-readStart;
|
|
||||||
if(readTime>stime) {
|
|
||||||
stime=readTime;
|
|
||||||
}else {
|
|
||||||
stime=(stime*99+readTime)/100;
|
|
||||||
}
|
|
||||||
if(stime<3000000000L) {
|
|
||||||
stime=3000000000L;
|
|
||||||
}
|
|
||||||
|
|
||||||
//System.out.println(readTime);
|
|
||||||
kplink.setSoTimeout((int) (stime/1000000));
|
|
||||||
if(kpp==null)
|
|
||||||
break;
|
|
||||||
switch (kpp.getType()) {
|
|
||||||
case KLALBPacket.PING:
|
|
||||||
sendPacket(new PONGPacket(((PINGPacket) kpp).getTime(),kpp.getRcvtime(),System.nanoTime()), -1);
|
|
||||||
break;
|
|
||||||
case KLALBPacket.PONG:
|
|
||||||
PONGPacket png=(PONGPacket) kpp;
|
|
||||||
long ul=png.getRcvtime()-( png.getTimepingsnd()+(png.getTimepongsnd()-png.getTimepingrcv()));
|
|
||||||
//System.out.println(toString()+"\t"+ul);
|
|
||||||
monitor.updateLatency (ul);
|
|
||||||
long DsndDelayFactor=png.getTimepingrcv()- png.getTimepingsnd();
|
|
||||||
long DrcvDelayFactor=png.getRcvtime()- png.getTimepongsnd();
|
|
||||||
//sndDelayFactor=DsndDelayFactor;
|
|
||||||
//rcvDelayFactor=DrcvDelayFactor;
|
|
||||||
if(sndDelayFactor==Long.MIN_VALUE) {
|
|
||||||
sndDelayFactor=DsndDelayFactor;
|
|
||||||
}else {
|
|
||||||
sndDelayFactor=(sndDelayFactor+ DsndDelayFactor)/2;
|
|
||||||
}
|
}
|
||||||
if(rcvDelayFactor==Long.MIN_VALUE) {
|
} catch (IOException e) {
|
||||||
rcvDelayFactor=DrcvDelayFactor;
|
}
|
||||||
}else {
|
|
||||||
rcvDelayFactor=(rcvDelayFactor+ DrcvDelayFactor)/2;
|
|
||||||
}
|
|
||||||
LockSupport.unpark(tlock);
|
|
||||||
break;
|
|
||||||
case KLALBPacket.VADDRREQ:
|
|
||||||
sendPacket(new VADDRPacket(localVaddrSupplier.get()), -1);
|
|
||||||
break;
|
|
||||||
case KLALBPacket.VADDR:
|
|
||||||
remoteVaddr=((VADDRPacket) kpp).getVaddr();
|
|
||||||
sendPacket(new VADDRACKPacket(), -1);
|
|
||||||
break;
|
|
||||||
case KLALBPacket.VADDRACK:
|
|
||||||
if(fst) {
|
|
||||||
monitor.resetCoolingTime();
|
|
||||||
monitor.setState(Monitor.ONLINE);
|
|
||||||
fst=false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case KLALBPacket.TEST:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
while(rec==null) {
|
|
||||||
Thread.sleep(1);
|
|
||||||
}
|
|
||||||
rec.accept(KLALBRemoteLine.this,kpp);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
Thread.yield();
|
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
if (closed) {
|
||||||
} catch (InterruptedException e) {
|
break;
|
||||||
e.printStackTrace();
|
|
||||||
} finally {
|
|
||||||
monitor.setState(Monitor.OFFLINE);
|
|
||||||
try {
|
|
||||||
if(kplink!=null)
|
|
||||||
kplink.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
|
// Thread.sleep(monitor.getCoolingTime());
|
||||||
|
lthd = Thread.currentThread();
|
||||||
|
LockSupport.parkNanos(coll.getCoolingTime(monitor.getReliability()));
|
||||||
|
// coll.incCoolingTime();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(closed) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
//Thread.sleep(monitor.getCoolingTime());
|
|
||||||
lthd=Thread.currentThread();
|
|
||||||
LockSupport.parkNanos(monitor.getCoolingTime()*1000000L);
|
|
||||||
monitor.incCoolingTime();
|
|
||||||
|
|
||||||
}
|
|
||||||
endRecord();
|
|
||||||
|
|
||||||
}).start();
|
}).start();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void flushKPL() throws IOException {
|
||||||
|
kplink.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private KLALBPacket readPacketFromKPL() throws IOException {
|
private KLALBPacket readPacketFromKPL() throws IOException {
|
||||||
KLALBPacket packet=kplink.readPacket();
|
KLALBPacket packet = kplink.readPacket();
|
||||||
/*if(!(packet instanceof PINGPacket) )
|
if (showpacket) {
|
||||||
if(!(packet instanceof PONGPacket) )
|
if (!(packet instanceof PINGPacket))
|
||||||
System.out.println("RX:" + packet);*/
|
if (!(packet instanceof PONGPacket))
|
||||||
if(packet!=null)
|
System.out.println("RX:" + packet);
|
||||||
monitor.getInTrafficAL().addAndGet(packet.getLength());
|
}
|
||||||
|
if (packet != null) {
|
||||||
|
monitor.getInTrafficAL().addAndGet(packet.getLength());
|
||||||
|
if (klalbController != null)
|
||||||
|
klalbController.getLinkMonitor().getInTrafficAL().addAndGet(packet.getLength());
|
||||||
|
}
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writePacketToKPL(KLALBPacket packet) throws IOException {
|
private void writePacketToKPL(KLALBPacket packet) throws IOException {
|
||||||
monitor.getOutTrafficAL().addAndGet(packet.getLength());
|
monitor.getOutTrafficAL().addAndGet(packet.getLength());
|
||||||
|
if (klalbController != null)
|
||||||
|
klalbController.getLinkMonitor().getOutTrafficAL().addAndGet(packet.getLength());
|
||||||
kplink.writePacket(packet);
|
kplink.writePacket(packet);
|
||||||
|
|
||||||
/*if(!(packet instanceof PINGPacket) )
|
if (showpacket) {
|
||||||
if(!(packet instanceof PONGPacket) )
|
if (!(packet instanceof PINGPacket))
|
||||||
System.err.println("TX:" + packet);*/
|
if (!(packet instanceof PONGPacket))
|
||||||
|
System.err.println("TX:" + packet);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close() {
|
public void close() {
|
||||||
closed=true;
|
closed = true;
|
||||||
|
monitor.setState(MonitorData.OFFLINE);
|
||||||
|
pressure = false;
|
||||||
try {
|
try {
|
||||||
if(kplink!=null)
|
if (kplink != null)
|
||||||
kplink.close();
|
kplink.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isClosed() {
|
public boolean isClosed() {
|
||||||
return closed;
|
return closed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private volatile long timeTurnSleep = System.nanoTime();
|
||||||
|
|
||||||
private volatile long time = System.nanoTime();
|
private volatile long time = System.nanoTime();
|
||||||
private volatile long pingInterval=1000000000L;
|
private volatile long pingInterval = 50000000L;
|
||||||
|
private volatile long pingIntervalSleep = 200000000L;
|
||||||
|
|
||||||
|
private void resetSleepTimer() {
|
||||||
|
timeTurnSleep = System.nanoTime();
|
||||||
|
}
|
||||||
|
|
||||||
private boolean checkPingTime() {
|
private boolean checkPingTime() {
|
||||||
long cu = System.nanoTime();
|
long cu = System.nanoTime();
|
||||||
if (cu - time > pingInterval) {
|
if (cu - time > ((System.nanoTime() - timeTurnSleep > 500000000) ? pingIntervalSleep
|
||||||
|
: Math.min(pingIntervalSleep, pingInterval))) {
|
||||||
time = cu;
|
time = cu;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private volatile BiConsumer<KLALBRemoteLine, KLALBPacket> rec;
|
private volatile BiConsumer<KLALBRemoteLine, KLALBPacket> rec;
|
||||||
|
|
||||||
//private Object lock=new Object();
|
|
||||||
private volatile Thread tlock;
|
private volatile Thread tlock;
|
||||||
private List<SumQueue<KLALBPacket>> sendDequeList =new ArrayList<SumQueue<KLALBPacket>>();
|
|
||||||
{
|
private ConcurrentLinkedQueue<KLALBPacket> IsendDequeList = new ConcurrentLinkedQueue<KLALBPacket>();
|
||||||
for(int i=0;i<12;i++) {
|
|
||||||
sendDequeList.add(new SumQueue<KLALBPacket>(new ConcurrentLinkedQueue<>()));
|
private PriorityBlockingQueue<KLALBPacket> sendDequeList = new PriorityBlockingQueue<KLALBPacket>();
|
||||||
}
|
|
||||||
|
public PriorityBlockingQueue<KLALBPacket> getQueue() {
|
||||||
|
return sendDequeList;
|
||||||
}
|
}
|
||||||
private KLALBPacket getNextPacket() {
|
|
||||||
for (Iterator<SumQueue<KLALBPacket>> iterator = sendDequeList.iterator(); iterator.hasNext();) {
|
protected void sendPacket(KLALBPacket blk) {
|
||||||
SumQueue<KLALBPacket> queue = (SumQueue<KLALBPacket>) iterator.next();
|
sendDequeList.add(blk);
|
||||||
KLALBPacket v=queue.poll();
|
|
||||||
if(v!=null)
|
|
||||||
return v;
|
|
||||||
if(monitor.getLatencyCurr()>(monitor.getLatencyMin()<<3)) {
|
|
||||||
//System.out.println(monitor.getLatencyCurr()+" "+monitor.getLatencyMin());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
private long sumNextPacketSize() {
|
|
||||||
long i=0;
|
|
||||||
for (Iterator<SumQueue<KLALBPacket>> iterator = sendDequeList.iterator(); iterator.hasNext();) {
|
|
||||||
SumQueue<KLALBPacket> queue = (SumQueue<KLALBPacket>) iterator.next();
|
|
||||||
i+=queue.getSumValue();
|
|
||||||
}
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
private long sumNextPacketCount() {
|
|
||||||
long i=0;
|
|
||||||
for (Iterator<SumQueue<KLALBPacket>> iterator = sendDequeList.iterator(); iterator.hasNext();) {
|
|
||||||
SumQueue<KLALBPacket> queue = (SumQueue<KLALBPacket>) iterator.next();
|
|
||||||
i+=queue.size();
|
|
||||||
}
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendPacket(KLALBPacket kp) {
|
|
||||||
sendPacket(kp, 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendPacket(KLALBPacket blk,int prio) {
|
|
||||||
sendDequeList.get(prio+1).add(blk);
|
|
||||||
LockSupport.unpark(tlock);
|
LockSupport.unpark(tlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPacketReceiver(BiConsumer<KLALBRemoteLine,KLALBPacket> rec) {
|
private void sendIPacket(KLALBPacket blk) {
|
||||||
|
IsendDequeList.add(blk);
|
||||||
|
LockSupport.unpark(tlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPacketReceiver(BiConsumer<KLALBRemoteLine, KLALBPacket> rec) {
|
||||||
this.rec = rec;
|
this.rec = rec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void remoeFromSendQueue(KLALBPacket klalbPacket) {
|
/*public void remoeFromSendQueue(KLALBPacket klalbPacket) {
|
||||||
for (Iterator<SumQueue<KLALBPacket>> iterator = sendDequeList.iterator(); iterator.hasNext();) {
|
sendDequeList.remove(klalbPacket);
|
||||||
SumQueue<KLALBPacket> queue = iterator.next();
|
}*/
|
||||||
queue.removeIf((x)->{
|
|
||||||
return x.equals(klalbPacket);
|
public long statLengthBefore(long l) {
|
||||||
});
|
AtomicLong al = new AtomicLong();
|
||||||
}
|
for (Iterator<KLALBPacket> iterator = sendDequeList.iterator(); iterator.hasNext();) {
|
||||||
}
|
KLALBPacket queue = iterator.next();
|
||||||
|
if (queue.getPriority() <= l) {
|
||||||
public long statLengthBefore(int priority) {
|
al.addAndGet(queue.getLength());
|
||||||
AtomicLong al=new AtomicLong();
|
|
||||||
int n=0;
|
|
||||||
for (Iterator<SumQueue<KLALBPacket>> iterator = sendDequeList.iterator(); iterator.hasNext();n++) {
|
|
||||||
if(n>priority) {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
SumQueue<KLALBPacket> queue = iterator.next();
|
|
||||||
al.addAndGet(queue.getSumValue());
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return al.get();
|
return al.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
private long sndDelayFactor=Long.MIN_VALUE;
|
|
||||||
private long rcvDelayFactor=Long.MIN_VALUE;
|
|
||||||
|
|
||||||
public long getSndDelayFactor() {
|
|
||||||
return sndDelayFactor;
|
|
||||||
}
|
|
||||||
public long getRcvDelayFactor() {
|
|
||||||
return rcvDelayFactor;
|
|
||||||
}
|
|
||||||
private volatile long predictTime;
|
private volatile long predictTime;
|
||||||
public void runPredict(KLALBPacket curr,int priority) {
|
|
||||||
predictTime=sndDelayFactor;
|
public void runPredict() {
|
||||||
//System.out.println(this+" "+sndDelayFactor);
|
//predictTime = monitor.getOutDelayPredicted();
|
||||||
long al=0;
|
predictTime=monitor.getOutDelay();
|
||||||
al=statLengthBefore(priority);
|
/*
|
||||||
long speed=getMonitor(). getOutSpeed();
|
* long al=0; al=statLengthBefore(5); long speed=getMonitor().getOutSpeedAvg();
|
||||||
if(speed==0) {
|
* // spdlmt.setLimitspeed(speed*2+65536); if(speed==0) { if(al>0) {
|
||||||
if(al>0) {
|
* predictTime=Long.MAX_VALUE; } }else { predictTime+=al*1000000000L/speed; }
|
||||||
predictTime=Long.MAX_VALUE;
|
*/
|
||||||
}
|
|
||||||
}else {
|
|
||||||
predictTime+=al*1000000000L/speed;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(KLALBRemoteLine o2) {
|
public int compareTo(KLALBRemoteLine o2) {
|
||||||
long t1=this.predictTime;
|
long t1 = this.predictTime;
|
||||||
long t2=o2.predictTime;
|
long t2 = o2.predictTime;
|
||||||
if(t1>t2) {
|
if (t1 > t2) {
|
||||||
return 1;
|
return 1;
|
||||||
}else if(t1<t2){
|
} else if (t1 < t2) {
|
||||||
return -1;
|
return -1;
|
||||||
}else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void reconnectImmediately() {
|
public void reconnectImmediately() {
|
||||||
if(lthd!=null) {
|
if (lthd != null) {
|
||||||
LockSupport.unpark(lthd);
|
LockSupport.unpark(lthd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void dislink() {
|
||||||
|
if (kplink != null) {
|
||||||
|
try {
|
||||||
|
kplink.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final TESTPacket testPacket = new TESTPacket();
|
||||||
|
private volatile boolean pressure = false;
|
||||||
|
private SpeedLimiter pressureSpeed = new SpeedLimiter(32768);
|
||||||
|
|
||||||
|
public void pressureTest() {
|
||||||
|
if (pressure)
|
||||||
|
throw new IllegalStateException("Test already start");
|
||||||
|
this.pressure = true;
|
||||||
|
pressureSpeed.setLimitspeed(32768);
|
||||||
|
ThreadTool.makeVThreadIfSupport("压力测试控制线程", () -> {
|
||||||
|
while (pressure) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(100);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
if (getMonitor().getOutSpeed() < pressureSpeed.getLimitspeed() * 2 / 3
|
||||||
|
|| getMonitor().getInDelayMin() * 30 < getMonitor().getInDelay()) {
|
||||||
|
pressure = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pressureSpeed.setLimitspeed(pressureSpeed.getLimitspeed() * 400 / 399);
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getPredictedTime() {
|
||||||
|
return predictTime;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,179 @@
|
|||||||
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.SocketException;
|
||||||
|
import java.net.SocketTimeoutException;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||||
|
import org.kne.cloud.network.Proxy;
|
||||||
|
import org.kne.cloud.network.SocketListener;
|
||||||
|
import org.kne.cloud.network.monitor.MonitorData;
|
||||||
|
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonParser;
|
||||||
|
import com.google.gson.JsonPrimitive;
|
||||||
|
|
||||||
|
public class KLALBRemoteManagement {
|
||||||
|
SocketListener slr;
|
||||||
|
private KLALBProxySystem klalbProxySystem;
|
||||||
|
public KLALBRemoteManagement(KLALBProxySystem klalbProxySystem) throws IOException {
|
||||||
|
this(klalbProxySystem,new MultipurposeSocketAddress("127.9.9.9", 49573));
|
||||||
|
}
|
||||||
|
public KLALBRemoteManagement(KLALBProxySystem klalbProxySystem,MultipurposeSocketAddress listen) throws IOException {
|
||||||
|
this.klalbProxySystem=klalbProxySystem;
|
||||||
|
slr=new SocketListener(listen);
|
||||||
|
slr.setCon((srcv)->{
|
||||||
|
try {
|
||||||
|
srcv.setSoTimeout(10000);
|
||||||
|
byte[]input= srcv.getInputStream().readAllBytes();
|
||||||
|
srcv.shutdownInput();
|
||||||
|
String req=new String(input,Charset.forName("UTF-8"));
|
||||||
|
System.out.println("远程管理请求:"+req);
|
||||||
|
String rsp=processSignal(req);
|
||||||
|
System.out.println("远程管理响应:"+rsp);
|
||||||
|
srcv.getOutputStream().write(rsp.getBytes(Charset.forName("UTF-8")));
|
||||||
|
srcv.shutdownOutput();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}finally {
|
||||||
|
try {
|
||||||
|
srcv.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
public KLALBProxySystem getKlalbProxySystem() {
|
||||||
|
return klalbProxySystem;
|
||||||
|
}
|
||||||
|
private String processSignal(String req) {
|
||||||
|
JsonObject jreq= (JsonObject) new JsonParser().parse(req);
|
||||||
|
JsonObject jrsp=new JsonObject();
|
||||||
|
|
||||||
|
|
||||||
|
String reqt=jreq.getAsJsonPrimitive("REQ").getAsString();
|
||||||
|
jrsp.addProperty("RSP", reqt);
|
||||||
|
switch (reqt) {
|
||||||
|
case "GETLINES":
|
||||||
|
JsonArray lines=new JsonArray();
|
||||||
|
List<KLALBRemoteLine>lineslist= klalbProxySystem.getKlalbController().getLines();
|
||||||
|
synchronized (lineslist) {
|
||||||
|
for (Iterator<KLALBRemoteLine> iterator = lineslist.iterator(); iterator.hasNext();) {
|
||||||
|
KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) iterator.next();
|
||||||
|
if(klalbRemoteLine.getSocketAddress()==null)
|
||||||
|
continue;
|
||||||
|
JsonObject jklbrl=new JsonObject();
|
||||||
|
jklbrl.addProperty("ipport", klalbRemoteLine.getSocketAddress().toString());
|
||||||
|
jklbrl.addProperty("state",MonitorData.parseStateToString( klalbRemoteLine.getMonitor().getState()));
|
||||||
|
|
||||||
|
jklbrl.addProperty("Vaddr", klalbRemoteLine.getRemoteVaddr().getHostAddress());
|
||||||
|
|
||||||
|
jklbrl.addProperty("uploadspeed", klalbRemoteLine.getMonitor().getOutSpeed());
|
||||||
|
jklbrl.addProperty("downloadspeed", klalbRemoteLine.getMonitor().getInSpeed());
|
||||||
|
|
||||||
|
jklbrl.addProperty("uploadspeedavg", klalbRemoteLine.getMonitor().getOutSpeedAvg());
|
||||||
|
jklbrl.addProperty("downloadspeedavg", klalbRemoteLine.getMonitor().getInSpeedAvg());
|
||||||
|
|
||||||
|
jklbrl.addProperty("uploadtraffic", klalbRemoteLine.getMonitor().getOutTraffic());
|
||||||
|
jklbrl.addProperty("downloadtraffic", klalbRemoteLine.getMonitor().getInTraffic());
|
||||||
|
|
||||||
|
jklbrl.addProperty("uploaddelay",klalbRemoteLine.getMonitor().getOutDelay() );
|
||||||
|
jklbrl.addProperty("downloaddelay", klalbRemoteLine.getMonitor().getInDelay());
|
||||||
|
|
||||||
|
jklbrl.addProperty("uploaddelaymin",klalbRemoteLine.getMonitor().getOutDelayMin() );
|
||||||
|
jklbrl.addProperty("downloaddelaymin", klalbRemoteLine.getMonitor().getInDelayMin());
|
||||||
|
lines.add(jklbrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jrsp.add("table", lines);
|
||||||
|
break;
|
||||||
|
case "ADDLINE":
|
||||||
|
String mip=jreq.getAsJsonPrimitive("ipport").getAsString();
|
||||||
|
try {
|
||||||
|
|
||||||
|
jrsp.addProperty ("Vaddr",klalbProxySystem.getKlalbController().getRemoteVaddrBySocketAddress(new MultipurposeSocketAddress(mip)).getHostAddress());
|
||||||
|
} catch (SocketTimeoutException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "GETSELFLINES":
|
||||||
|
JsonArray lines2=new JsonArray();
|
||||||
|
List<MultipurposeSocketAddress>selflineslist=klalbProxySystem.getKlalbController().getSelflineTable();
|
||||||
|
synchronized (selflineslist) {
|
||||||
|
for (Iterator<MultipurposeSocketAddress> iterator = selflineslist.iterator(); iterator.hasNext();) {
|
||||||
|
MultipurposeSocketAddress multipurposeSocketAddress = (MultipurposeSocketAddress) iterator.next();
|
||||||
|
lines2.add(new JsonPrimitive(multipurposeSocketAddress.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jrsp.add("table", lines2);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case "ADDSELFLINE":
|
||||||
|
String mips=jreq.getAsJsonPrimitive("ipport").getAsString();
|
||||||
|
List<MultipurposeSocketAddress>selflineslist2=klalbProxySystem.getKlalbController().getSelflineTable();
|
||||||
|
synchronized (selflineslist2) {
|
||||||
|
selflineslist2.add(new MultipurposeSocketAddress(mips));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "REMOVESELFLINE":
|
||||||
|
String mipsr=jreq.getAsJsonPrimitive("ipport").getAsString();
|
||||||
|
List<MultipurposeSocketAddress>selflineslist21=klalbProxySystem.getKlalbController().getSelflineTable();
|
||||||
|
synchronized (selflineslist21) {
|
||||||
|
selflineslist21.add(new MultipurposeSocketAddress(mipsr));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "GETLINKMONITOR":
|
||||||
|
jrsp.addProperty("uploadspeed", klalbProxySystem.getKlalbController().getLinkMonitor().getOutSpeed());
|
||||||
|
jrsp.addProperty("downloadspeed", klalbProxySystem.getKlalbController().getLinkMonitor().getInSpeed());
|
||||||
|
|
||||||
|
jrsp.addProperty("uploadspeedavg", klalbProxySystem.getKlalbController().getLinkMonitor().getOutSpeedAvg());
|
||||||
|
jrsp.addProperty("downloadspeedavg", klalbProxySystem.getKlalbController().getLinkMonitor().getInSpeedAvg());
|
||||||
|
|
||||||
|
jrsp.addProperty("uploadtraffic", klalbProxySystem.getKlalbController().getLinkMonitor().getOutTraffic());
|
||||||
|
jrsp.addProperty("downloadtraffic", klalbProxySystem.getKlalbController().getLinkMonitor().getInTraffic());
|
||||||
|
|
||||||
|
break;
|
||||||
|
case "OPENMONITORUI":
|
||||||
|
klalbProxySystem.getKLALBGUI().setVisible(true);
|
||||||
|
break;
|
||||||
|
case "GETSOCKETBRIDGE":
|
||||||
|
JsonArray bridges=new JsonArray();
|
||||||
|
Set<Proxy> pxy=klalbProxySystem.getProxys();
|
||||||
|
synchronized (pxy) {
|
||||||
|
for (Iterator<Proxy> iterator = pxy.iterator(); iterator.hasNext();) {
|
||||||
|
Proxy proxy = (Proxy) iterator.next();
|
||||||
|
bridges.add(klalbProxySystem.createJsonObjectByProxy(proxy));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jrsp.add("table", bridges);
|
||||||
|
break;
|
||||||
|
case "ADDSOCKETBRIDGE":
|
||||||
|
JsonObject jpxy= jreq.getAsJsonObject("socketbridge");
|
||||||
|
Set<Proxy> pxy2=klalbProxySystem.getProxys();
|
||||||
|
synchronized (pxy2) {
|
||||||
|
try {
|
||||||
|
pxy2.add(klalbProxySystem.createProxyByJson(jpxy));
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
System.out.println("未知请求类型:"+reqt);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return jrsp.toString();
|
||||||
|
}
|
||||||
|
public void close() {
|
||||||
|
slr.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +1,8 @@
|
|||||||
package org.kne.cloud.network.klalb;
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
import java.awt.AWTException;
|
import java.awt.AWTException;
|
||||||
import java.awt.BorderLayout;
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Dimension;
|
|
||||||
import java.awt.MenuItem;
|
import java.awt.MenuItem;
|
||||||
import java.awt.PopupMenu;
|
import java.awt.PopupMenu;
|
||||||
import java.awt.SystemTray;
|
import java.awt.SystemTray;
|
||||||
@@ -13,34 +11,18 @@ import java.awt.event.ActionEvent;
|
|||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.awt.event.ComponentEvent;
|
import java.awt.event.ComponentEvent;
|
||||||
import java.awt.event.ComponentListener;
|
import java.awt.event.ComponentListener;
|
||||||
import java.awt.event.ItemEvent;
|
|
||||||
import java.awt.event.ItemListener;
|
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.ConnectException;
|
|
||||||
import java.net.UnknownHostException;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import javax.swing.JButton;
|
|
||||||
import javax.swing.JComboBox;
|
|
||||||
import javax.swing.JOptionPane;
|
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.border.LineBorder;
|
||||||
|
|
||||||
import org.kne.cloud.network.MultipurposeSocketAddress;
|
|
||||||
import org.kne.cloud.network.SocketBridge;
|
|
||||||
import org.kne.cloud.network.SocketListener;
|
|
||||||
import org.kne.cloud.network.ThreadTool;
|
|
||||||
import org.kne.ui.XFrame;
|
import org.kne.ui.XFrame;
|
||||||
import org.kne.ui.YScrollPane;
|
import org.kne.ui.YScrollPane;
|
||||||
import javax.swing.JProgressBar;
|
|
||||||
|
|
||||||
public class KLALBStateGUI extends XFrame {
|
public class KLALBStateGUI extends XFrame {
|
||||||
private BufferedImage bi;
|
private BufferedImage bi;
|
||||||
@@ -50,6 +32,10 @@ public class KLALBStateGUI extends XFrame {
|
|||||||
private SystemTray st;
|
private SystemTray st;
|
||||||
|
|
||||||
private TrayIcon ti;
|
private TrayIcon ti;
|
||||||
|
|
||||||
|
public KLALBStateGUI(KLALBController kpcje) throws IOException {
|
||||||
|
this(kpcje ,CONST.klalb+" network accelerator V"+CONST.klalbver);
|
||||||
|
}
|
||||||
public KLALBStateGUI(KLALBController kc,String title) throws IOException {
|
public KLALBStateGUI(KLALBController kc,String title) throws IOException {
|
||||||
setResizable(false);
|
setResizable(false);
|
||||||
try {
|
try {
|
||||||
@@ -59,9 +45,14 @@ public class KLALBStateGUI extends XFrame {
|
|||||||
}
|
}
|
||||||
if(bi!=null)
|
if(bi!=null)
|
||||||
setIconImage(bi);
|
setIconImage(bi);
|
||||||
|
|
||||||
|
setTitleColor(new Color(255, 255, 255, 250));
|
||||||
|
//getTitlelabel().setFont(UIEnv.getFont().deriveFont(17.0f));
|
||||||
|
getTitlepanel().setBorder(new LineBorder(Color.LIGHT_GRAY));
|
||||||
|
/*
|
||||||
setTitleColor(new Color(0,0,0,80));
|
setTitleColor(new Color(0,0,0,80));
|
||||||
getContentPane().setBackground(new Color(0,0,0,80));
|
getContentPane().setBackground(new Color(0,0,0,80));
|
||||||
getTitlelabel().setForeground(Color.WHITE);
|
getTitlelabel().setForeground(Color.WHITE);*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -194,8 +185,9 @@ public class KLALBStateGUI extends XFrame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException, InterruptedException {//,new MultipurposeSocketAddress("frp-mom.top:22226"),new MultipurposeSocketAddress("0.0.0.0:26468")
|
public static void main(String[] args) throws IOException, InterruptedException {//,new MultipurposeSocketAddress("frp-mom.top:22226"),new MultipurposeSocketAddress("0.0.0.0:26468")
|
||||||
KLALBStateGUI kcg=new KLALBStateGUI(new KLALBController(),"KNE云网络负载均衡客户端 V2.0");
|
KLALBStateGUI kcg=new KLALBStateGUI(new KLALBController());
|
||||||
Thread.sleep(10000);
|
kcg.setVisible(true);
|
||||||
kcg.close();
|
//Thread.sleep(10000);
|
||||||
|
//kcg.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,645 @@
|
|||||||
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
|
import java.awt.AWTException;
|
||||||
|
import java.awt.BorderLayout;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.MenuItem;
|
||||||
|
import java.awt.PopupMenu;
|
||||||
|
import java.awt.SystemTray;
|
||||||
|
import java.awt.TrayIcon;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.awt.event.ComponentEvent;
|
||||||
|
import java.awt.event.ComponentListener;
|
||||||
|
import java.awt.event.ItemEvent;
|
||||||
|
import java.awt.event.ItemListener;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.ConnectException;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Timer;
|
||||||
|
import java.util.TimerTask;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import javax.management.monitor.Monitor;
|
||||||
|
import javax.swing.ButtonGroup;
|
||||||
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JComboBox;
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
|
import org.jfree.chart.ChartFactory;
|
||||||
|
import org.jfree.chart.ChartPanel;
|
||||||
|
import org.jfree.chart.JFreeChart;
|
||||||
|
import org.jfree.chart.plot.dial.DialLayer;
|
||||||
|
import org.jfree.chart.plot.dial.DialPlot;
|
||||||
|
import org.jfree.chart.plot.dial.DialPointer;
|
||||||
|
import org.jfree.chart.plot.dial.DialTextAnnotation;
|
||||||
|
import org.jfree.chart.plot.dial.StandardDialFrame;
|
||||||
|
import org.jfree.chart.plot.dial.StandardDialRange;
|
||||||
|
import org.jfree.chart.plot.dial.StandardDialScale;
|
||||||
|
import org.jfree.chart.ui.RectangleEdge;
|
||||||
|
import org.jfree.chart.ui.RectangleInsets;
|
||||||
|
import org.jfree.data.general.Dataset;
|
||||||
|
import org.jfree.data.general.DefaultValueDataset;
|
||||||
|
import org.jfree.data.general.ValueDataset;
|
||||||
|
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||||
|
import org.kne.cloud.network.SocketBridge;
|
||||||
|
import org.kne.cloud.network.SocketListener;
|
||||||
|
import org.kne.cloud.network.ThreadTool;
|
||||||
|
import org.kne.cloud.network.klalb.KLALBController;
|
||||||
|
import org.kne.cloud.network.monitor.MonitorData;
|
||||||
|
import org.kne.ui.XFrame;
|
||||||
|
import org.kne.ui.YScrollPane;
|
||||||
|
import javax.swing.JProgressBar;
|
||||||
|
import javax.swing.border.LineBorder;
|
||||||
|
import javax.swing.JTabbedPane;
|
||||||
|
import javax.swing.JMenuBar;
|
||||||
|
import javax.swing.JMenu;
|
||||||
|
import javax.swing.JRadioButtonMenuItem;
|
||||||
|
import javax.swing.JCheckBoxMenuItem;
|
||||||
|
import java.awt.GridLayout;
|
||||||
|
import java.awt.Image;
|
||||||
|
import java.awt.FlowLayout;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.SwingConstants;
|
||||||
|
import java.awt.Font;
|
||||||
|
|
||||||
|
public class KLALBStateGUI2 extends XFrame {
|
||||||
|
|
||||||
|
private TimerTask tsk,tsk2,tsk3;
|
||||||
|
|
||||||
|
private SystemTray st;
|
||||||
|
|
||||||
|
private TrayIcon ti;
|
||||||
|
|
||||||
|
private long rate=200;
|
||||||
|
|
||||||
|
private Timer t,t2;
|
||||||
|
|
||||||
|
private JCheckBoxMenuItem showoffline;
|
||||||
|
|
||||||
|
|
||||||
|
private DefaultValueDataset upSpeed;
|
||||||
|
|
||||||
|
private DialTextAnnotation upSpeedText;
|
||||||
|
|
||||||
|
private DialTextAnnotation downSpeedText;
|
||||||
|
|
||||||
|
private DefaultValueDataset downSpeed;
|
||||||
|
|
||||||
|
private DefaultValueDataset upEfficiency;
|
||||||
|
|
||||||
|
private DialTextAnnotation upEfficiencyText;
|
||||||
|
|
||||||
|
private DialTextAnnotation downEfficiencyText;
|
||||||
|
|
||||||
|
private DefaultValueDataset downEfficiency;
|
||||||
|
|
||||||
|
private YScrollPane ysp;
|
||||||
|
|
||||||
|
private static BufferedImage bi;
|
||||||
|
|
||||||
|
public static Image getKLALBIcon() {
|
||||||
|
if(bi==null)
|
||||||
|
try {
|
||||||
|
bi = ImageIO.read(KLALBStateGUI2.class.getResourceAsStream("/assets/KNEL.png"));
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return bi;
|
||||||
|
}
|
||||||
|
|
||||||
|
public KLALBStateGUI2(KLALBController kpcje) {
|
||||||
|
this(kpcje ,CONST.klalb+" network accelerator V"+CONST.klalbver);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @wbp.parser.constructor
|
||||||
|
*/
|
||||||
|
public KLALBStateGUI2(KLALBController kc,String title) {
|
||||||
|
//setResizable(false);
|
||||||
|
Image bix=getKLALBIcon();
|
||||||
|
if(bix!=null)
|
||||||
|
setIconImage(bix);
|
||||||
|
setTitleColor(new Color(255, 255, 255, 250));
|
||||||
|
//getTitlelabel().setFont(UIEnv.getFont().deriveFont(17.0f));
|
||||||
|
getTitlepanel().setBorder(new LineBorder(Color.LIGHT_GRAY));
|
||||||
|
//getContentPane().setBackground(new Color(0,0,0,0));
|
||||||
|
/*setTitleColor(new Color(0,0,0,80));
|
||||||
|
getContentPane().setBackground(new Color(0,0,0,80));
|
||||||
|
getTitlelabel().setForeground(Color.WHITE);*/
|
||||||
|
|
||||||
|
|
||||||
|
JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
|
||||||
|
getContentPane().add(tabbedPane, BorderLayout.CENTER);
|
||||||
|
|
||||||
|
JPanel overview = new JPanel();
|
||||||
|
overview.setOpaque(false);
|
||||||
|
tabbedPane.addTab("Overview", null, overview, null);
|
||||||
|
overview.setLayout(new BorderLayout(0, 0));
|
||||||
|
JPanel dashboard = new JPanel();
|
||||||
|
dashboard.setOpaque(false);
|
||||||
|
overview.add(dashboard, BorderLayout.CENTER);
|
||||||
|
{
|
||||||
|
upSpeed = new DefaultValueDataset(0);
|
||||||
|
DialPlot dpup=new DialPlot();
|
||||||
|
dpup.setDataset(upSpeed);
|
||||||
|
StandardDialFrame sdfs=new StandardDialFrame();
|
||||||
|
sdfs.setVisible(false);
|
||||||
|
dpup.setDialFrame(sdfs);
|
||||||
|
StandardDialScale sds=new StandardDialScale(0, 100, -120, -300, 10, 5);
|
||||||
|
sds.setTickRadius(0.8);
|
||||||
|
sds.setTickLabelsVisible(false);
|
||||||
|
dpup.addScale(0, sds);
|
||||||
|
|
||||||
|
StandardDialRange sdrr=new StandardDialRange(0, 70,Color.GREEN);
|
||||||
|
sdrr.setInnerRadius(0.82);
|
||||||
|
sdrr.setOuterRadius(0.83);
|
||||||
|
dpup.addLayer(sdrr);
|
||||||
|
|
||||||
|
StandardDialRange sdrr2=new StandardDialRange(70, 90,Color.YELLOW);
|
||||||
|
sdrr2.setInnerRadius(0.82);
|
||||||
|
sdrr2.setOuterRadius(0.83);
|
||||||
|
dpup.addLayer(sdrr2);
|
||||||
|
|
||||||
|
StandardDialRange sdrr3=new StandardDialRange(90, 100,Color.RED);
|
||||||
|
sdrr3.setInnerRadius(0.82);
|
||||||
|
sdrr3.setOuterRadius(0.83);
|
||||||
|
dpup.addLayer(sdrr3);
|
||||||
|
|
||||||
|
DialPointer.Pointer dp=new DialPointer.Pointer();
|
||||||
|
dp.setRadius(0.7);
|
||||||
|
dp.setFillPaint(Color.RED);
|
||||||
|
dp.setOutlinePaint(Color.RED);
|
||||||
|
dpup.addLayer(dp);
|
||||||
|
|
||||||
|
upSpeedText = new DialTextAnnotation("0%");
|
||||||
|
upSpeedText.setFont(upSpeedText.getFont().deriveFont(12));
|
||||||
|
dpup.addLayer(upSpeedText);
|
||||||
|
|
||||||
|
JFreeChart jfup= new JFreeChart(dpup);
|
||||||
|
jfup.setBorderPaint(Color.WHITE);
|
||||||
|
jfup.setTitle("Upload speed");
|
||||||
|
jfup.getTitle().setPosition(RectangleEdge.BOTTOM);
|
||||||
|
dpup.setView(0, 0, 1, 1);
|
||||||
|
ChartPanel cpup=new ChartPanel(jfup);
|
||||||
|
cpup.setPreferredSize(new Dimension(150, 165));
|
||||||
|
cpup.setSize(cpup.getPreferredSize());
|
||||||
|
cpup.setBackground(Color.WHITE);
|
||||||
|
cpup.setBorder(new LineBorder(Color.LIGHT_GRAY));
|
||||||
|
dashboard.add(cpup);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
downSpeed = new DefaultValueDataset(0);
|
||||||
|
DialPlot dpup1=new DialPlot();
|
||||||
|
dpup1.setDataset(downSpeed);
|
||||||
|
StandardDialFrame sdfs1=new StandardDialFrame();
|
||||||
|
sdfs1.setVisible(false);
|
||||||
|
dpup1.setDialFrame(sdfs1);
|
||||||
|
StandardDialScale sds1=new StandardDialScale(0, 100, -120, -300, 10, 5);
|
||||||
|
sds1.setTickRadius(0.8);
|
||||||
|
sds1.setTickLabelsVisible(false);
|
||||||
|
dpup1.addScale(0, sds1);
|
||||||
|
|
||||||
|
StandardDialRange sdrr1=new StandardDialRange(0, 70,Color.GREEN);
|
||||||
|
sdrr1.setInnerRadius(0.82);
|
||||||
|
sdrr1.setOuterRadius(0.83);
|
||||||
|
dpup1.addLayer(sdrr1);
|
||||||
|
|
||||||
|
StandardDialRange sdrr21=new StandardDialRange(70, 90,Color.YELLOW);
|
||||||
|
sdrr21.setInnerRadius(0.82);
|
||||||
|
sdrr21.setOuterRadius(0.83);
|
||||||
|
dpup1.addLayer(sdrr21);
|
||||||
|
|
||||||
|
StandardDialRange sdrr31=new StandardDialRange(90, 100,Color.RED);
|
||||||
|
sdrr31.setInnerRadius(0.82);
|
||||||
|
sdrr31.setOuterRadius(0.83);
|
||||||
|
dpup1.addLayer(sdrr31);
|
||||||
|
|
||||||
|
DialPointer.Pointer dp1=new DialPointer.Pointer();
|
||||||
|
dp1.setRadius(0.7);
|
||||||
|
dp1.setFillPaint(Color.GREEN);
|
||||||
|
dp1.setOutlinePaint(Color.GREEN);
|
||||||
|
dpup1.addLayer(dp1);
|
||||||
|
|
||||||
|
downSpeedText = new DialTextAnnotation("0%");
|
||||||
|
downSpeedText.setFont(downSpeedText.getFont().deriveFont(12));
|
||||||
|
dpup1.addLayer(downSpeedText);
|
||||||
|
|
||||||
|
JFreeChart jfup1= new JFreeChart(dpup1);
|
||||||
|
jfup1.setBorderPaint(Color.WHITE);
|
||||||
|
jfup1.setTitle("Download speed");
|
||||||
|
jfup1.getTitle().setPosition(RectangleEdge.BOTTOM);
|
||||||
|
dpup1.setView(0, 0, 1, 1);
|
||||||
|
ChartPanel cpup1=new ChartPanel(jfup1);
|
||||||
|
cpup1.setPreferredSize(new Dimension(150, 165));
|
||||||
|
cpup1.setSize(cpup1.getPreferredSize());
|
||||||
|
cpup1.setBackground(Color.WHITE);
|
||||||
|
cpup1.setBorder(new LineBorder(Color.LIGHT_GRAY));
|
||||||
|
dashboard.add(cpup1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
upEfficiency = new DefaultValueDataset(0);
|
||||||
|
DialPlot dpup=new DialPlot();
|
||||||
|
dpup.setDataset(upEfficiency);
|
||||||
|
StandardDialFrame sdfs=new StandardDialFrame();
|
||||||
|
sdfs.setVisible(false);
|
||||||
|
dpup.setDialFrame(sdfs);
|
||||||
|
StandardDialScale sds=new StandardDialScale(0, 100, -120, -300, 10, 5);
|
||||||
|
sds.setTickRadius(0.8);
|
||||||
|
sds.setTickLabelsVisible(false);
|
||||||
|
dpup.addScale(0, sds);
|
||||||
|
|
||||||
|
StandardDialRange sdrr=new StandardDialRange(0, 70,Color.RED);
|
||||||
|
sdrr.setInnerRadius(0.82);
|
||||||
|
sdrr.setOuterRadius(0.83);
|
||||||
|
dpup.addLayer(sdrr);
|
||||||
|
|
||||||
|
StandardDialRange sdrr2=new StandardDialRange(70, 90,Color.YELLOW);
|
||||||
|
sdrr2.setInnerRadius(0.82);
|
||||||
|
sdrr2.setOuterRadius(0.83);
|
||||||
|
dpup.addLayer(sdrr2);
|
||||||
|
|
||||||
|
StandardDialRange sdrr3=new StandardDialRange(90, 100,Color.GREEN);
|
||||||
|
sdrr3.setInnerRadius(0.82);
|
||||||
|
sdrr3.setOuterRadius(0.83);
|
||||||
|
dpup.addLayer(sdrr3);
|
||||||
|
|
||||||
|
DialPointer.Pointer dp=new DialPointer.Pointer();
|
||||||
|
dp.setRadius(0.7);
|
||||||
|
dp.setFillPaint(Color.RED);
|
||||||
|
dp.setOutlinePaint(Color.RED);
|
||||||
|
dpup.addLayer(dp);
|
||||||
|
|
||||||
|
upEfficiencyText = new DialTextAnnotation("0%");
|
||||||
|
upEfficiencyText.setFont(upEfficiencyText.getFont().deriveFont(12));
|
||||||
|
dpup.addLayer(upEfficiencyText);
|
||||||
|
|
||||||
|
JFreeChart jfup= new JFreeChart(dpup);
|
||||||
|
jfup.setBorderPaint(Color.WHITE);
|
||||||
|
jfup.setTitle("Upload bandwidth efficiency");
|
||||||
|
jfup.getTitle().setPosition(RectangleEdge.BOTTOM);
|
||||||
|
dpup.setView(0, 0, 1, 1);
|
||||||
|
ChartPanel cpup=new ChartPanel(jfup);
|
||||||
|
cpup.setPreferredSize(new Dimension(150, 165));
|
||||||
|
cpup.setSize(cpup.getPreferredSize());
|
||||||
|
cpup.setBackground(Color.WHITE);
|
||||||
|
cpup.setBorder(new LineBorder(Color.LIGHT_GRAY));
|
||||||
|
dashboard.add(cpup);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
downEfficiency = new DefaultValueDataset(0);
|
||||||
|
DialPlot dpup1=new DialPlot();
|
||||||
|
dpup1.setDataset(downEfficiency);
|
||||||
|
StandardDialFrame sdfs1=new StandardDialFrame();
|
||||||
|
sdfs1.setVisible(false);
|
||||||
|
dpup1.setDialFrame(sdfs1);
|
||||||
|
StandardDialScale sds1=new StandardDialScale(0, 100, -120, -300, 10, 5);
|
||||||
|
sds1.setTickRadius(0.8);
|
||||||
|
sds1.setTickLabelsVisible(false);
|
||||||
|
dpup1.addScale(0, sds1);
|
||||||
|
|
||||||
|
StandardDialRange sdrr1=new StandardDialRange(0, 70,Color.RED);
|
||||||
|
sdrr1.setInnerRadius(0.82);
|
||||||
|
sdrr1.setOuterRadius(0.83);
|
||||||
|
dpup1.addLayer(sdrr1);
|
||||||
|
|
||||||
|
StandardDialRange sdrr21=new StandardDialRange(70, 90,Color.YELLOW);
|
||||||
|
sdrr21.setInnerRadius(0.82);
|
||||||
|
sdrr21.setOuterRadius(0.83);
|
||||||
|
dpup1.addLayer(sdrr21);
|
||||||
|
|
||||||
|
StandardDialRange sdrr31=new StandardDialRange(90, 100,Color.GREEN);
|
||||||
|
sdrr31.setInnerRadius(0.82);
|
||||||
|
sdrr31.setOuterRadius(0.83);
|
||||||
|
dpup1.addLayer(sdrr31);
|
||||||
|
|
||||||
|
DialPointer.Pointer dp1=new DialPointer.Pointer();
|
||||||
|
dp1.setRadius(0.7);
|
||||||
|
dp1.setFillPaint(Color.GREEN);
|
||||||
|
dp1.setOutlinePaint(Color.GREEN);
|
||||||
|
dpup1.addLayer(dp1);
|
||||||
|
|
||||||
|
downEfficiencyText = new DialTextAnnotation("0%");
|
||||||
|
downEfficiencyText.setFont(downEfficiencyText.getFont().deriveFont(12));
|
||||||
|
dpup1.addLayer(downEfficiencyText);
|
||||||
|
|
||||||
|
JFreeChart jfup1= new JFreeChart(dpup1);
|
||||||
|
jfup1.setBorderPaint(Color.WHITE);
|
||||||
|
jfup1.setTitle("Download bandwidth efficiency");
|
||||||
|
jfup1.getTitle().setPosition(RectangleEdge.BOTTOM);
|
||||||
|
dpup1.setView(0, 0, 1, 1);
|
||||||
|
ChartPanel cpup1=new ChartPanel(jfup1);
|
||||||
|
cpup1.setPreferredSize(new Dimension(150, 165));
|
||||||
|
cpup1.setSize(cpup1.getPreferredSize());
|
||||||
|
cpup1.setBackground(Color.WHITE);
|
||||||
|
cpup1.setBorder(new LineBorder(Color.LIGHT_GRAY));
|
||||||
|
dashboard.add(cpup1);
|
||||||
|
}
|
||||||
|
|
||||||
|
JLabel ashboard = new JLabel("Dashboard");
|
||||||
|
ashboard.setFont(new Font("宋体", Font.PLAIN, 18));
|
||||||
|
ashboard.setHorizontalAlignment(SwingConstants.CENTER);
|
||||||
|
overview.add(ashboard, BorderLayout.NORTH);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ysp = new YScrollPane(730);
|
||||||
|
ysp.setOpaque(false);
|
||||||
|
tabbedPane.add(ysp);
|
||||||
|
tabbedPane.setTitleAt(1, "Remote lines");
|
||||||
|
JPanel wv = ysp.getView();
|
||||||
|
|
||||||
|
JMenuBar menuBar = new JMenuBar();
|
||||||
|
getContentPane().add(menuBar, BorderLayout.NORTH);
|
||||||
|
|
||||||
|
JMenu mnNewMenu = new JMenu("Monitor");
|
||||||
|
menuBar.add(mnNewMenu);
|
||||||
|
/*
|
||||||
|
JMenu mnNewMenu_1 = new JMenu("Update frequency");
|
||||||
|
mnNewMenu.add(mnNewMenu_1);
|
||||||
|
ButtonGroup bg=new ButtonGroup();
|
||||||
|
JRadioButtonMenuItem rdbtnmntmNewRadioItem = new JRadioButtonMenuItem("0.5s");
|
||||||
|
mnNewMenu_1.add(rdbtnmntmNewRadioItem);
|
||||||
|
bg.add(rdbtnmntmNewRadioItem);
|
||||||
|
rdbtnmntmNewRadioItem.addActionListener(new ActionListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
rate=500;
|
||||||
|
|
||||||
|
createRefreshTask(kc, ysp);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
JRadioButtonMenuItem rdbtnmntmNewRadioItem_1 = new JRadioButtonMenuItem("0.2s");
|
||||||
|
mnNewMenu_1.add(rdbtnmntmNewRadioItem_1);
|
||||||
|
bg.add(rdbtnmntmNewRadioItem_1);
|
||||||
|
rdbtnmntmNewRadioItem_1.setSelected(true);
|
||||||
|
rdbtnmntmNewRadioItem_1.addActionListener(new ActionListener() {
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
rate=200;
|
||||||
|
|
||||||
|
createRefreshTask(kc, ysp);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
JRadioButtonMenuItem rdbtnmntmNewRadioItem_2 = new JRadioButtonMenuItem("0.1s");
|
||||||
|
mnNewMenu_1.add(rdbtnmntmNewRadioItem_2);
|
||||||
|
bg.add(rdbtnmntmNewRadioItem_2);
|
||||||
|
|
||||||
|
rdbtnmntmNewRadioItem_2.addActionListener(new ActionListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
rate=100;
|
||||||
|
|
||||||
|
createRefreshTask(kc, ysp);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
JRadioButtonMenuItem rdbtnmntmNewRadioItem_21 = new JRadioButtonMenuItem("0.05s");
|
||||||
|
mnNewMenu_1.add(rdbtnmntmNewRadioItem_21);
|
||||||
|
bg.add(rdbtnmntmNewRadioItem_21);
|
||||||
|
rdbtnmntmNewRadioItem_21.addActionListener(new ActionListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
rate=50;
|
||||||
|
|
||||||
|
createRefreshTask(kc, ysp);
|
||||||
|
}
|
||||||
|
});*/
|
||||||
|
|
||||||
|
|
||||||
|
showoffline = new JCheckBoxMenuItem("Show offline remotelines");
|
||||||
|
mnNewMenu.add(showoffline);
|
||||||
|
/*JProgressBar progressBar = new JProgressBar();
|
||||||
|
progressBar.setIndeterminate(true);
|
||||||
|
progressBar.setForeground(Color.YELLOW);
|
||||||
|
progressBar.setBorder(null);
|
||||||
|
progressBar.setPreferredSize(new Dimension(100, 4));
|
||||||
|
ysp.add(progressBar, BorderLayout.NORTH);*/
|
||||||
|
wv.addComponentListener(new ComponentListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void componentShown(ComponentEvent e) {
|
||||||
|
// TODO 自动生成的方法存根
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void componentResized(ComponentEvent e) {
|
||||||
|
// TODO 自动生成的方法存根
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void componentMoved(ComponentEvent e) {
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void componentHidden(ComponentEvent e) {
|
||||||
|
// TODO 自动生成的方法存根
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
setTitle(title);
|
||||||
|
setSize(770, 490);
|
||||||
|
setLocationRelativeTo(null);
|
||||||
|
|
||||||
|
//setVisible(true);
|
||||||
|
|
||||||
|
if (SystemTray.isSupported()) {
|
||||||
|
st = SystemTray.getSystemTray();
|
||||||
|
ti = new TrayIcon(bi);
|
||||||
|
ti.setImageAutoSize(true);
|
||||||
|
PopupMenu jpm = new PopupMenu();
|
||||||
|
MenuItem mix = new MenuItem("open");
|
||||||
|
mix.addActionListener(new ActionListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
setVisible(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
jpm.add(mix);
|
||||||
|
MenuItem mi = new MenuItem("exit");
|
||||||
|
mi.addActionListener(new ActionListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
jpm.add(mi);
|
||||||
|
ti.setPopupMenu(jpm);
|
||||||
|
try {
|
||||||
|
st.add(ti);
|
||||||
|
} catch (AWTException e1) {
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
|
ti.addActionListener((x) -> {
|
||||||
|
setVisible(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//repaint();
|
||||||
|
|
||||||
|
t2 = new Timer("仪表盘刷新线程",true);
|
||||||
|
t = new Timer("状态刷新线程",true);
|
||||||
|
createRefreshTask(kc, ysp);
|
||||||
|
}
|
||||||
|
private void createRefreshTask(KLALBController kc, YScrollPane ysp) {
|
||||||
|
if(tsk!=null) {
|
||||||
|
tsk.cancel();
|
||||||
|
}
|
||||||
|
tsk=new TimerTask() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
Object[]kll;
|
||||||
|
kll=kc.getLines().toArray();
|
||||||
|
|
||||||
|
loop:for (int ix = 0; ix < kll.length; ix++) {
|
||||||
|
KLALBRemoteLine ent = (KLALBRemoteLine) kll[ix];
|
||||||
|
/*if(ent.getMonitor().getState()!=MonitorData.ONLINE) {
|
||||||
|
continue loop;
|
||||||
|
}*/
|
||||||
|
Component[] count=ysp.getView().getComponents();
|
||||||
|
for (int i = 0; i < count.length; i++) {
|
||||||
|
Component tp=count[i];
|
||||||
|
if(tp instanceof TPanel2) {
|
||||||
|
if(((TPanel2) tp).getTunnel().equals(ent)) {
|
||||||
|
tp.setVisible(showoffline.isSelected()||ent.getMonitor().getState()==MonitorData.ONLINE);
|
||||||
|
continue loop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TPanel2 tp=new TPanel2(ent);
|
||||||
|
tp.setVisible(showoffline.isSelected()||ent.getMonitor().getState()==MonitorData.ONLINE);
|
||||||
|
ysp.getView().add(tp);
|
||||||
|
}
|
||||||
|
Component[] count=ysp.getView().getComponents();
|
||||||
|
for (int i = 0; i < count.length; i++) {
|
||||||
|
Component tp=count[i];
|
||||||
|
if(tp instanceof TPanel2) {
|
||||||
|
/*if((((TPanel2) tp).getTunnel().getMonitor().getState())!=MonitorData.ONLINE)
|
||||||
|
{
|
||||||
|
ysp.getView().remove(tp);
|
||||||
|
continue;
|
||||||
|
}*/
|
||||||
|
if(kc.getLines().contains(((TPanel2) tp).getTunnel())) {
|
||||||
|
try {
|
||||||
|
((TPanel2) tp).updateTraffic();
|
||||||
|
}catch(RuntimeException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
ysp.getView().remove(tp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ysp.updateScrool();
|
||||||
|
//repaint();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
t.scheduleAtFixedRate(tsk, 200, 100);
|
||||||
|
if(tsk2!=null) {
|
||||||
|
tsk2.cancel();
|
||||||
|
}
|
||||||
|
tsk2=new TimerTask() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
upSpeedText.setLabel(KLALBUtils.bytesUnit(kc.getLinkMonitor().getOutSpeedAvg())+"/s");
|
||||||
|
upSpeed.setValue(upSpeed.getValue().doubleValue()*0.95+kc.getLinkMonitor().getOutSpeed()*100.0/(50*1024*1024)*0.05);
|
||||||
|
|
||||||
|
downSpeedText.setLabel(KLALBUtils.bytesUnit(kc.getLinkMonitor().getInSpeedAvg())+"/s");
|
||||||
|
downSpeed.setValue(downSpeed.getValue().doubleValue()*0.95+kc.getLinkMonitor().getInSpeed()*100.0/(50*1024*1024)*0.05);
|
||||||
|
|
||||||
|
double outefi=kc.getDatatMonitor().getOutSpeedAvg2()*100.0D/kc.getLinkMonitor().getOutSpeedAvg2();
|
||||||
|
if(Double.isFinite(outefi)) {
|
||||||
|
upEfficiency.setValue(upEfficiency.getValue().doubleValue()*0.95+ outefi*0.05);
|
||||||
|
upEfficiencyText.setLabel(String.format("%.1f", upEfficiency.getValue().doubleValue())+"%");
|
||||||
|
}
|
||||||
|
|
||||||
|
double inefi=kc.getDatatMonitor().getInSpeedAvg2()*100.0D/kc.getLinkMonitor().getInSpeedAvg2();
|
||||||
|
if(Double.isFinite(inefi)) {
|
||||||
|
downEfficiency.setValue(downEfficiency.getValue().doubleValue()*0.95+ inefi*0.05);
|
||||||
|
downEfficiencyText.setLabel(String.format("%.1f", downEfficiency.getValue().doubleValue())+"%");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
t2.scheduleAtFixedRate(tsk2, 200, 50);
|
||||||
|
|
||||||
|
if(tsk3!=null) {
|
||||||
|
tsk3.cancel();
|
||||||
|
}
|
||||||
|
tsk3=new TimerTask() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
Component[] count=ysp.getView().getComponents();
|
||||||
|
for (int i = 0; i < count.length; i++) {
|
||||||
|
Component tp=count[i];
|
||||||
|
if(tp instanceof TPanel2) {
|
||||||
|
try {
|
||||||
|
((TPanel2) tp).getMdg().updateTraffic();
|
||||||
|
}catch(RuntimeException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
t.scheduleAtFixedRate(tsk3, 200, 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() {
|
||||||
|
setVisible(false);
|
||||||
|
if(tsk!=null) {
|
||||||
|
tsk.cancel();
|
||||||
|
}
|
||||||
|
st.remove(ti);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws IOException, InterruptedException {//,new MultipurposeSocketAddress("frp-mom.top:22226"),new MultipurposeSocketAddress("0.0.0.0:26468")
|
||||||
|
KLALBStateGUI2 kcg=new KLALBStateGUI2(new KLALBController());
|
||||||
|
kcg.setVisible(true);
|
||||||
|
//Thread.sleep(10000);
|
||||||
|
//kcg.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,7 +13,9 @@ public class KLALBUtils {
|
|||||||
ByteArrayOutputStream bos=new ByteArrayOutputStream(8);
|
ByteArrayOutputStream bos=new ByteArrayOutputStream(8);
|
||||||
DataOutputStream dos=new DataOutputStream(bos);
|
DataOutputStream dos=new DataOutputStream(bos);
|
||||||
try {
|
try {
|
||||||
dos.writeLong(uuid.getMostSignificantBits());
|
long l=uuid.getMostSignificantBits();
|
||||||
|
l=(l&0x0000FFFFFFFFFFFFL)|0x2486000000000000L;
|
||||||
|
dos.writeLong(l);
|
||||||
dos.writeLong(uuid.getLeastSignificantBits());
|
dos.writeLong(uuid.getLeastSignificantBits());
|
||||||
dos.close();} catch (IOException e) {
|
dos.close();} catch (IOException e) {
|
||||||
// TODO 自动生成的 catch 块
|
// TODO 自动生成的 catch 块
|
||||||
@@ -31,6 +33,21 @@ public class KLALBUtils {
|
|||||||
System.out.println(uuidToIP(new UUID(-1,-1)));
|
System.out.println(uuidToIP(new UUID(-1,-1)));
|
||||||
}
|
}
|
||||||
public static String bytesUnit(long v) {
|
public static String bytesUnit(long v) {
|
||||||
|
if (v >= 1024L * 1024 * 1024 * 1024 * 1024) {
|
||||||
|
return String.format("%.1f", v / (1024.0 * 1024.0 * 1024.0 * 1024.0 * 1024.0)) + "PB";
|
||||||
|
} else if (v >= 1024L * 1024 * 1024 * 1024) {
|
||||||
|
return String.format("%.1f", v / (1024.0 * 1024.0 * 1024.0 * 1024.0)) + "TB";
|
||||||
|
} else if (v >= 1024L * 1024 * 1024) {
|
||||||
|
return String.format("%.1f", v / (1024.0 * 1024.0 * 1024.0)) + "GB";
|
||||||
|
} else if (v >= 1024L * 1024) {
|
||||||
|
return String.format("%.1f", v / (1024.0 * 1024.0)) + "MB";
|
||||||
|
} else if (v >= 1024L) {
|
||||||
|
return String.format("%.1f", v / (1024.0)) + "KB";
|
||||||
|
} else {
|
||||||
|
return v + "B";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static String bytesUnitSimp(long v) {
|
||||||
if(v>=1024L*1024*1024*1024*1024) {
|
if(v>=1024L*1024*1024*1024*1024) {
|
||||||
return format( v/(1024.0*1024.0*1024.0*1024.0*1024.0))+"P";
|
return format( v/(1024.0*1024.0*1024.0*1024.0*1024.0))+"P";
|
||||||
}else if(v>=1024L*1024*1024*1024) {
|
}else if(v>=1024L*1024*1024*1024) {
|
||||||
|
|||||||
@@ -6,17 +6,26 @@ import java.net.InetSocketAddress;
|
|||||||
import java.net.ServerSocket;
|
import java.net.ServerSocket;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.net.SocketImpl;
|
import java.net.SocketImpl;
|
||||||
|
import java.nio.channels.ServerSocketChannel;
|
||||||
|
import java.nio.channels.SocketChannel;
|
||||||
|
|
||||||
import org.kne.cloud.network.VirtualServerSocket;
|
import org.kne.cloud.network.VirtualServerSocket;
|
||||||
import org.kne.cloud.network.VirtualSocket;
|
import org.kne.cloud.network.VirtualSocket;
|
||||||
|
import org.kne.cloud.network.VirtualSocketImpl;
|
||||||
|
|
||||||
public class KLALBVirtualServerSocket extends VirtualServerSocket {
|
public class KLALBVirtualServerSocket extends VirtualServerSocket {
|
||||||
private KLALBController controler;
|
private KLALBController controler;
|
||||||
|
protected ServerSocketChannel channel;
|
||||||
public KLALBVirtualServerSocket(KLALBController controler) throws IOException {
|
public KLALBVirtualServerSocket(KLALBController controler) throws IOException {
|
||||||
super(controler.createVirtualImpl());
|
super(controler.createVirtualImpl());
|
||||||
this.controler=controler;
|
this.controler=controler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected KLALBVirtualSocketImpl getVirtualImpl() {
|
||||||
|
return (KLALBVirtualSocketImpl) super.getVirtualImpl();
|
||||||
|
}
|
||||||
|
|
||||||
public KLALBVirtualServerSocket(KLALBController controler,int port) throws IOException {
|
public KLALBVirtualServerSocket(KLALBController controler,int port) throws IOException {
|
||||||
this(controler,port, 50, null);
|
this(controler,port, 50, null);
|
||||||
}
|
}
|
||||||
@@ -52,4 +61,9 @@ public class KLALBVirtualServerSocket extends VirtualServerSocket {
|
|||||||
return s2;
|
return s2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServerSocketChannel getChannel() {
|
||||||
|
return channel;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,84 @@
|
|||||||
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.ServerSocket;
|
||||||
|
import java.net.SocketAddress;
|
||||||
|
import java.net.SocketOption;
|
||||||
|
import java.nio.channels.ServerSocketChannel;
|
||||||
|
import java.nio.channels.SocketChannel;
|
||||||
|
import java.nio.channels.spi.SelectorProvider;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class KLALBVirtualServerSocketChannel extends ServerSocketChannel {
|
||||||
|
private KLALBController controller;
|
||||||
|
|
||||||
|
private KLALBVirtualServerSocket serversocket;
|
||||||
|
|
||||||
|
protected KLALBVirtualServerSocketChannel(KLALBController controller) throws IOException {
|
||||||
|
super(null);
|
||||||
|
this.controller=controller;
|
||||||
|
this.serversocket=new KLALBVirtualServerSocket(controller);
|
||||||
|
serversocket.channel=this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public KLALBController getController() {
|
||||||
|
return controller;
|
||||||
|
}
|
||||||
|
public static ServerSocketChannel open(KLALBController controller2) throws IOException {
|
||||||
|
return new KLALBVirtualServerSocketChannel(controller2);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public <T> T getOption(SocketOption<T> name) throws IOException {
|
||||||
|
// TODO 自动生成的方法存根
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<SocketOption<?>> supportedOptions() {
|
||||||
|
// TODO 自动生成的方法存根
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServerSocketChannel bind(SocketAddress local, int backlog) throws IOException {
|
||||||
|
serversocket.bind(local, backlog);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> ServerSocketChannel setOption(SocketOption<T> name, T value) throws IOException {
|
||||||
|
// TODO 自动生成的方法存根
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServerSocket socket() {
|
||||||
|
return serversocket;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SocketChannel accept() throws IOException {
|
||||||
|
KLALBVirtualSocket sock=serversocket.accept();
|
||||||
|
return new KLALBVirtualSocketChannel(controller,sock);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SocketAddress getLocalAddress() throws IOException {
|
||||||
|
return serversocket.getLocalSocketAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void implCloseSelectableChannel() throws IOException {
|
||||||
|
serversocket.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void implConfigureBlocking(boolean block) throws IOException {
|
||||||
|
if(!block) {
|
||||||
|
throw new UnsupportedOperationException("Please use VirtualThread to configure Asynchronous IO");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.ServerSocket;
|
||||||
|
import java.nio.channels.ServerSocketChannel;
|
||||||
|
|
||||||
|
import javax.net.ServerSocketFactory;
|
||||||
|
|
||||||
|
import org.kne.cloud.network.ServerSocketChannelFactory;
|
||||||
|
|
||||||
|
public class KLALBVirtualServerSocketChannelFactory extends ServerSocketChannelFactory {
|
||||||
|
|
||||||
|
private KLALBController controller;
|
||||||
|
|
||||||
|
public KLALBVirtualServerSocketChannelFactory(KLALBController controller) {
|
||||||
|
super();
|
||||||
|
this.controller = controller;
|
||||||
|
}
|
||||||
|
|
||||||
|
public KLALBController getController() {
|
||||||
|
return controller;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public ServerSocketChannel createServerSocketChannel() throws IOException {
|
||||||
|
return KLALBVirtualServerSocketChannel.open(controller);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServerSocketChannel createServerSocketChannel(int port) throws IOException {
|
||||||
|
ServerSocketChannel ksc=createServerSocketChannel();
|
||||||
|
ksc.bind(new InetSocketAddress(port));
|
||||||
|
return ksc;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServerSocketChannel createServerSocketChannel(int port, int backlog) throws IOException {
|
||||||
|
ServerSocketChannel ksc=createServerSocketChannel();
|
||||||
|
ksc.bind(new InetSocketAddress(port),backlog);
|
||||||
|
return ksc;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServerSocketChannel createServerSocketChannel(int port, int backlog, InetAddress ifAddress) throws IOException {
|
||||||
|
ServerSocketChannel ksc=createServerSocketChannel();
|
||||||
|
ksc.bind(new InetSocketAddress(ifAddress,port),backlog);
|
||||||
|
return ksc;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -2,12 +2,20 @@ package org.kne.cloud.network.klalb;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
|
import java.nio.channels.SocketChannel;
|
||||||
|
|
||||||
import org.kne.cloud.network.VirtualSocket;
|
import org.kne.cloud.network.VirtualSocket;
|
||||||
|
import org.kne.cloud.network.VirtualSocketImpl;
|
||||||
|
|
||||||
public class KLALBVirtualSocket extends VirtualSocket {
|
public class KLALBVirtualSocket extends VirtualSocket {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected KLALBVirtualSocketImpl getVirtualImpl() {
|
||||||
|
return (KLALBVirtualSocketImpl) super.getVirtualImpl();
|
||||||
|
}
|
||||||
|
|
||||||
private KLALBController controler;
|
private KLALBController controler;
|
||||||
|
protected SocketChannel channel;
|
||||||
|
|
||||||
public KLALBVirtualSocket(KLALBController controler) throws SocketException {
|
public KLALBVirtualSocket(KLALBController controler) throws SocketException {
|
||||||
super(controler.createVirtualImpl());
|
super(controler.createVirtualImpl());
|
||||||
@@ -70,5 +78,19 @@ public class KLALBVirtualSocket extends VirtualSocket {
|
|||||||
public void associateSocket(Socket associateSocket) throws IOException {
|
public void associateSocket(Socket associateSocket) throws IOException {
|
||||||
((KLALBVirtualSocketImpl)getVirtualImpl()).associateSocket(associateSocket);
|
((KLALBVirtualSocketImpl)getVirtualImpl()).associateSocket(associateSocket);
|
||||||
}
|
}
|
||||||
|
public void associateSocketChannel(SocketChannel b) throws IOException{
|
||||||
|
((KLALBVirtualSocketImpl)getVirtualImpl()).associateSocketChannel(b);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public SocketChannel getChannel() {
|
||||||
|
return channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isConnectionPending() {
|
||||||
|
return ((KLALBVirtualSocketImpl)getVirtualImpl()).isConnectionPending();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,154 @@
|
|||||||
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.net.SocketAddress;
|
||||||
|
import java.net.SocketException;
|
||||||
|
import java.net.SocketOption;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.channels.SocketChannel;
|
||||||
|
import java.nio.channels.spi.SelectorProvider;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.kne.cloud.network.klalb.KLALBVirtualSocketImpl.KVSIInputStream;
|
||||||
|
import org.kne.cloud.network.klalb.KLALBVirtualSocketImpl.KVSIOutputStream;
|
||||||
|
|
||||||
|
public class KLALBVirtualSocketChannel extends SocketChannel{
|
||||||
|
|
||||||
|
private KLALBController controller;
|
||||||
|
|
||||||
|
private KLALBVirtualSocket socket;
|
||||||
|
|
||||||
|
protected KLALBVirtualSocketChannel(KLALBController controller) throws SocketException {
|
||||||
|
super(null);
|
||||||
|
this.controller=controller;
|
||||||
|
this.socket=new KLALBVirtualSocket(controller);
|
||||||
|
socket.channel=this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected KLALBVirtualSocketChannel(KLALBController controller, KLALBVirtualSocket sock) {
|
||||||
|
super(null);
|
||||||
|
this.controller=controller;
|
||||||
|
this.socket=sock;
|
||||||
|
socket.channel=this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SocketChannel open(KLALBController controller) throws SocketException {
|
||||||
|
return new KLALBVirtualSocketChannel(controller);
|
||||||
|
}
|
||||||
|
|
||||||
|
public KLALBController getController() {
|
||||||
|
return controller;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> T getOption(SocketOption<T> name) throws IOException {
|
||||||
|
// TODO 自动生成的方法存根
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<SocketOption<?>> supportedOptions() {
|
||||||
|
// TODO 自动生成的方法存根
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SocketChannel bind(SocketAddress local) throws IOException {
|
||||||
|
socket.bind(local);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> SocketChannel setOption(SocketOption<T> name, T value) throws IOException {
|
||||||
|
// TODO 自动生成的方法存根
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SocketChannel shutdownInput() throws IOException {
|
||||||
|
socket.shutdownInput();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SocketChannel shutdownOutput() throws IOException {
|
||||||
|
socket.shutdownOutput();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Socket socket() {
|
||||||
|
return socket;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isConnected() {
|
||||||
|
return socket.isConnected();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isConnectionPending() {
|
||||||
|
return socket.isConnectionPending();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean connect(SocketAddress remote) throws IOException {
|
||||||
|
socket.connect(remote);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean finishConnect() throws IOException {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SocketAddress getRemoteAddress() throws IOException {
|
||||||
|
return socket.getRemoteSocketAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read(ByteBuffer dst) throws IOException {
|
||||||
|
return ((KVSIInputStream)socket.getInputStream()).read(dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long read(ByteBuffer[] dsts, int offset, int length) throws IOException {
|
||||||
|
// TODO 自动生成的方法存根
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int write(ByteBuffer src) throws IOException {
|
||||||
|
return ((KVSIOutputStream)socket.getOutputStream()).write(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long write(ByteBuffer[] srcs, int offset, int length) throws IOException {
|
||||||
|
// TODO 自动生成的方法存根
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SocketAddress getLocalAddress() throws IOException {
|
||||||
|
return socket.getLocalSocketAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void implCloseSelectableChannel() throws IOException {
|
||||||
|
socket.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void implConfigureBlocking(boolean block) throws IOException {
|
||||||
|
if(!block) {
|
||||||
|
throw new UnsupportedOperationException("Please use VirtualThread to configure Asynchronous IO");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void associateSocketChannel(SocketChannel b) throws IOException {
|
||||||
|
socket.associateSocketChannel(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.nio.channels.SocketChannel;
|
||||||
|
|
||||||
|
import javax.net.SocketFactory;
|
||||||
|
|
||||||
|
import org.kne.cloud.network.SocketChannelFactory;
|
||||||
|
|
||||||
|
public class KLALBVirtualSocketChannelFactory extends SocketChannelFactory {
|
||||||
|
private KLALBController controller;
|
||||||
|
|
||||||
|
public KLALBVirtualSocketChannelFactory(KLALBController controller) {
|
||||||
|
super();
|
||||||
|
this.controller = controller;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public SocketChannel createSocketChannel() throws IOException {
|
||||||
|
return KLALBVirtualSocketChannel.open(controller);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public SocketChannel createSocketChannel(String arg0, int arg1) throws IOException, UnknownHostException {
|
||||||
|
SocketChannel sc=createSocketChannel();
|
||||||
|
sc.connect(new InetSocketAddress(arg0,arg1));
|
||||||
|
return sc;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SocketChannel createSocketChannel(InetAddress arg0, int arg1) throws IOException {
|
||||||
|
SocketChannel sc=createSocketChannel();
|
||||||
|
sc.connect(new InetSocketAddress(arg0,arg1));
|
||||||
|
return sc;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SocketChannel createSocketChannel(String arg0, int arg1, InetAddress arg2, int arg3)
|
||||||
|
throws IOException, UnknownHostException {
|
||||||
|
SocketChannel sc=createSocketChannel();
|
||||||
|
sc.bind(new InetSocketAddress(arg2, arg3));
|
||||||
|
sc.connect(new InetSocketAddress(arg0,arg1));
|
||||||
|
return sc;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SocketChannel createSocketChannel(InetAddress arg0, int arg1, InetAddress arg2, int arg3) throws IOException {
|
||||||
|
SocketChannel sc=createSocketChannel();
|
||||||
|
sc.bind(new InetSocketAddress(arg2, arg3));
|
||||||
|
sc.connect(new InetSocketAddress(arg0,arg1));
|
||||||
|
return sc;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -13,7 +13,7 @@ public class LineDecitionComparator implements Comparator<KLALBRemoteLine> {
|
|||||||
public LineDecitionComparator (List<KLALBRemoteLine> krs,KLALBPacket curr,int priority) {
|
public LineDecitionComparator (List<KLALBRemoteLine> krs,KLALBPacket curr,int priority) {
|
||||||
for (Iterator<KLALBRemoteLine> iterator = krs.iterator(); iterator.hasNext();) {
|
for (Iterator<KLALBRemoteLine> iterator = krs.iterator(); iterator.hasNext();) {
|
||||||
KLALBRemoteLine klalbRemoteSocket = (KLALBRemoteLine) iterator.next();
|
KLALBRemoteLine klalbRemoteSocket = (KLALBRemoteLine) iterator.next();
|
||||||
long x=klalbRemoteSocket.getSndDelayFactor();
|
long x=klalbRemoteSocket.getMonitor().getOutDelay();
|
||||||
//long x=klalbRemoteSocket.getMonitor().getLatency()>>1;
|
//long x=klalbRemoteSocket.getMonitor().getLatency()>>1;
|
||||||
/*long al=0;
|
/*long al=0;
|
||||||
al=klalbRemoteSocket.statLengthBefore(priority)+curr.getLength();
|
al=klalbRemoteSocket.statLengthBefore(priority)+curr.getLength();
|
||||||
|
|||||||
@@ -0,0 +1,207 @@
|
|||||||
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.GridLayout;
|
||||||
|
import java.awt.Image;
|
||||||
|
import java.awt.Stroke;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.Inet6Address;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.border.LineBorder;
|
||||||
|
|
||||||
|
import org.jfree.chart.ChartFactory;
|
||||||
|
import org.jfree.chart.ChartPanel;
|
||||||
|
import org.jfree.chart.JFreeChart;
|
||||||
|
import org.jfree.data.time.Millisecond;
|
||||||
|
import org.jfree.data.time.RegularTimePeriod;
|
||||||
|
import org.jfree.data.time.TimePeriod;
|
||||||
|
import org.jfree.data.time.TimeSeries;
|
||||||
|
import org.jfree.data.time.TimeSeriesCollection;
|
||||||
|
import org.kne.cloud.network.monitor.MonitorData;
|
||||||
|
import org.kne.ui.XFrame;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
|
import java.awt.BorderLayout;
|
||||||
|
|
||||||
|
import javax.swing.ImageIcon;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JTextField;
|
||||||
|
import javax.swing.JButton;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.Font;
|
||||||
|
import javax.swing.SwingConstants;
|
||||||
|
|
||||||
|
public class LineMonitorGUI extends XFrame{
|
||||||
|
private TimeSeries spdup=new TimeSeries("Upload speed");
|
||||||
|
private TimeSeries spddown=new TimeSeries("Download speed");
|
||||||
|
|
||||||
|
private TimeSeries delayup=new TimeSeries("Upload delay");
|
||||||
|
private TimeSeries delaydown=new TimeSeries("Download delay");
|
||||||
|
|
||||||
|
private TimeSeries delayupmin=new TimeSeries("Upload delay minimum");
|
||||||
|
private TimeSeries delaydownmin=new TimeSeries("Download delay minimum");
|
||||||
|
|
||||||
|
private KLALBRemoteLine tr;
|
||||||
|
private JTextField vaddrs;
|
||||||
|
private JFreeChart jfc;
|
||||||
|
private JFreeChart jfce;
|
||||||
|
private JLabel spdp;
|
||||||
|
private JLabel delp;
|
||||||
|
//private ChartPanel delp;
|
||||||
|
//private ChartPanel spdp;
|
||||||
|
public LineMonitorGUI(KLALBRemoteLine t) {
|
||||||
|
this.tr=t;
|
||||||
|
setSize(700, 700);
|
||||||
|
setLocationRelativeTo(null);
|
||||||
|
|
||||||
|
Image bi=KLALBStateGUI2.getKLALBIcon();
|
||||||
|
if(bi!=null)
|
||||||
|
setIconImage(bi);
|
||||||
|
setTitle("Line Monitor:"+t.getMonitor().getName());
|
||||||
|
setTitleColor(new Color(255, 255, 255, 250));
|
||||||
|
//getTitlelabel().setFont(UIEnv.getFont().deriveFont(17.0f));
|
||||||
|
getTitlepanel().setBorder(new LineBorder(Color.LIGHT_GRAY));
|
||||||
|
|
||||||
|
JPanel jp=new JPanel();
|
||||||
|
jp.setLayout(new GridLayout(2, 1));
|
||||||
|
getContentPane().add(jp);
|
||||||
|
|
||||||
|
TimeSeriesCollection tsc=new TimeSeriesCollection();
|
||||||
|
tsc.addSeries(spdup);
|
||||||
|
tsc.addSeries(spddown);
|
||||||
|
jfc = ChartFactory.createTimeSeriesChart("Speed monitor", "Time(s)", "Speed(KiB/s)", tsc);
|
||||||
|
jfc.getXYPlot().getDomainAxis().setFixedAutoRange(5000);
|
||||||
|
jfc.getXYPlot().setBackgroundPaint(Color.BLACK);
|
||||||
|
jfc.getXYPlot().getRenderer().setSeriesPaint(0,Color.RED);
|
||||||
|
jfc.getXYPlot().getRenderer().setSeriesPaint(1,Color.GREEN);
|
||||||
|
spdp = new JLabel();
|
||||||
|
spdp.setBorder(new LineBorder(Color.DARK_GRAY));
|
||||||
|
jp.add(spdp);
|
||||||
|
|
||||||
|
TimeSeriesCollection tsce=new TimeSeriesCollection();
|
||||||
|
tsce.addSeries(delayup);
|
||||||
|
tsce.addSeries(delaydown);
|
||||||
|
|
||||||
|
tsce.addSeries(delayupmin);
|
||||||
|
tsce.addSeries(delaydownmin);
|
||||||
|
jfce = ChartFactory.createTimeSeriesChart("Delay monitor", "Time(s)", "Delay(ms)", tsce);
|
||||||
|
jfce.getXYPlot().getDomainAxis().setFixedAutoRange(5000);
|
||||||
|
jfce.getXYPlot().setBackgroundPaint(Color.BLACK);
|
||||||
|
jfce.getXYPlot().getRenderer().setSeriesPaint(0,Color.RED);
|
||||||
|
jfce.getXYPlot().getRenderer().setSeriesPaint(1,Color.GREEN);
|
||||||
|
|
||||||
|
BasicStroke dotted = new BasicStroke(2, BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND, 0, new float[]{0,6,0,6}, 0);
|
||||||
|
jfce.getXYPlot().getRenderer().setSeriesPaint(2,Color.RED);
|
||||||
|
jfce.getXYPlot().getRenderer().setSeriesStroke(2, dotted);
|
||||||
|
jfce.getXYPlot().getRenderer().setSeriesPaint(3,Color.GREEN);
|
||||||
|
jfce.getXYPlot().getRenderer().setSeriesStroke(3, dotted);
|
||||||
|
delp = new JLabel();
|
||||||
|
delp.setBorder(new LineBorder(Color.DARK_GRAY));
|
||||||
|
jp.add(delp);
|
||||||
|
|
||||||
|
JPanel panel = new JPanel();
|
||||||
|
panel.setOpaque(false);
|
||||||
|
getContentPane().add(panel, BorderLayout.NORTH);
|
||||||
|
panel.setLayout(new GridLayout(2, 1, 0, 0));
|
||||||
|
|
||||||
|
vaddrs = new JTextField();
|
||||||
|
vaddrs.setHorizontalAlignment(SwingConstants.CENTER);
|
||||||
|
vaddrs.setFont(new Font("宋体", Font.PLAIN, 14));
|
||||||
|
vaddrs.setEditable(false);
|
||||||
|
panel.add(vaddrs);
|
||||||
|
vaddrs.setColumns(10);
|
||||||
|
|
||||||
|
JPanel panel_1 = new JPanel();
|
||||||
|
panel.add(panel_1);
|
||||||
|
Dimension dms=new Dimension(140, 20);
|
||||||
|
JButton btnNewButton = new JButton("Force disconnect");
|
||||||
|
btnNewButton.setPreferredSize(dms);
|
||||||
|
btnNewButton.addActionListener(new ActionListener() {
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
tr.dislink();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
btnNewButton.setForeground(Color.RED);
|
||||||
|
panel_1.add(btnNewButton);
|
||||||
|
|
||||||
|
JButton btnNewButton_1 = new JButton("Force reconnect");
|
||||||
|
btnNewButton_1.setPreferredSize(dms);
|
||||||
|
btnNewButton_1.addActionListener(new ActionListener() {
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
tr.reconnectImmediately();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
btnNewButton_1.setForeground(Color.GREEN);
|
||||||
|
panel_1.add(btnNewButton_1);
|
||||||
|
|
||||||
|
JButton btnNewButton_2 = new JButton("Pressure test");
|
||||||
|
btnNewButton_2.setPreferredSize(dms);
|
||||||
|
btnNewButton_2.addActionListener(new ActionListener() {
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
tr.pressureTest();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
panel_1.add(btnNewButton_2);
|
||||||
|
btnNewButton_2.setForeground(Color.BLUE);
|
||||||
|
}
|
||||||
|
public void recordData() {
|
||||||
|
if(isVisible()) {
|
||||||
|
Millisecond ms= new Millisecond();
|
||||||
|
spdup.addOrUpdate(ms, tr.getMonitor().getOutSpeed()/1024.0);
|
||||||
|
spddown.addOrUpdate(ms, tr.getMonitor().getInSpeed()/1024.0);
|
||||||
|
|
||||||
|
|
||||||
|
Millisecond msu= new Millisecond(new Date(System.currentTimeMillis()-(System.nanoTime()- tr.getMonitor().getRecentPingNanoTime())/1000000L));
|
||||||
|
delayup.addOrUpdate(msu, tr.getMonitor().getOutDelay()/1000000.0);
|
||||||
|
delaydown.addOrUpdate(msu, tr.getMonitor().getInDelay()/1000000.0);
|
||||||
|
|
||||||
|
//Millisecond msup= new Millisecond(new Date( tr.getMonitor().getUpdateDelayTime()+tr.getMonitor().getOutDelay()/1000000L));
|
||||||
|
delayupmin.addOrUpdate(ms, tr.getMonitor().getOutDelayPredicted()/1000000.0);
|
||||||
|
delaydownmin.addOrUpdate(ms, tr.getMonitor().getInDelayPredicted()/1000000.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateTraffic() {
|
||||||
|
switch (tr.getMonitor().getState()) {
|
||||||
|
case MonitorData.OFFLINE:
|
||||||
|
getTitlelabel().setForeground(Color.RED);
|
||||||
|
break;
|
||||||
|
case MonitorData.CONNECTING:
|
||||||
|
getTitlelabel().setForeground(Color.YELLOW);
|
||||||
|
break;
|
||||||
|
case MonitorData.ONLINE:
|
||||||
|
getTitlelabel().setForeground(Color.GREEN);
|
||||||
|
|
||||||
|
recordData();
|
||||||
|
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(isVisible()) {
|
||||||
|
ImageIcon i1=new ImageIcon(jfc.createBufferedImage(spdp.getWidth(), spdp.getHeight()));
|
||||||
|
ImageIcon i2=new ImageIcon(jfce.createBufferedImage(delp.getWidth(), delp.getHeight()));
|
||||||
|
spdp.setIcon(i1);
|
||||||
|
delp.setIcon(i2);
|
||||||
|
//spddown.fireSeriesChanged();
|
||||||
|
//delaydown.fireSeriesChanged();
|
||||||
|
|
||||||
|
Inet6Address i6a= tr.getRemoteVaddr();
|
||||||
|
if(i6a==null) {
|
||||||
|
vaddrs.setText("unknown");
|
||||||
|
}else {
|
||||||
|
vaddrs.setText(i6a.getHostAddress());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
|
public class MemUseTest {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws InterruptedException {
|
||||||
|
Thread.sleep(1000);
|
||||||
|
Runtime r=Runtime.getRuntime();
|
||||||
|
System.out.println("total:"+r.totalMemory()+" max:"+r.maxMemory()+" free:"+r.freeMemory());
|
||||||
|
while(true) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,277 +0,0 @@
|
|||||||
package org.kne.cloud.network.klalb;
|
|
||||||
|
|
||||||
import java.util.Timer;
|
|
||||||
import java.util.TimerTask;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
import static org.kne.cloud.network.klalb.KLALBUtils.*;
|
|
||||||
public class Monitor {
|
|
||||||
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
public void setName(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
private static Timer t=new Timer("带宽测量线程",true);
|
|
||||||
|
|
||||||
|
|
||||||
private TimerTask ptt=new TimerTask() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
runMonitor();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
protected void runMonitor() {
|
|
||||||
updateSpeed();
|
|
||||||
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
protected void finalize() throws Throwable {
|
|
||||||
ptt.cancel();
|
|
||||||
}
|
|
||||||
private static AtomicInteger ai=new AtomicInteger();
|
|
||||||
public Monitor() {
|
|
||||||
this.name="Line"+ai.getAndIncrement();
|
|
||||||
t.scheduleAtFixedRate(ptt, 1000, 1000);
|
|
||||||
}
|
|
||||||
public Monitor(String name) {
|
|
||||||
this.name=name;
|
|
||||||
t.scheduleAtFixedRate(ptt, 1000, 1000);
|
|
||||||
}
|
|
||||||
private AtomicLong inTraffic=new AtomicLong();
|
|
||||||
private AtomicLong outTraffic=new AtomicLong();
|
|
||||||
|
|
||||||
|
|
||||||
private AtomicLong inTrafficOld=new AtomicLong();
|
|
||||||
private AtomicLong outTrafficOld=new AtomicLong();
|
|
||||||
|
|
||||||
private volatile long inSpeed;
|
|
||||||
private volatile long outSpeed;
|
|
||||||
|
|
||||||
|
|
||||||
private volatile long inSpeedAvg;
|
|
||||||
private volatile long outSpeedAvg;
|
|
||||||
|
|
||||||
|
|
||||||
private volatile long inSpeedMax=1024*1024*1024;
|
|
||||||
private volatile long outSpeedMax=1024*1024*1024;
|
|
||||||
|
|
||||||
public void setInSpeedMax(long inSpeedMax) {
|
|
||||||
this.inSpeedMax = inSpeedMax;
|
|
||||||
}
|
|
||||||
public void setOutSpeedMax(long outSpeedMax) {
|
|
||||||
this.outSpeedMax = outSpeedMax;
|
|
||||||
}
|
|
||||||
private volatile long latencyAvg =Long.MIN_VALUE;
|
|
||||||
private volatile long latencyMin =Long.MIN_VALUE;
|
|
||||||
private volatile long latencyCurr =Long.MIN_VALUE;
|
|
||||||
private volatile long jitter ;
|
|
||||||
|
|
||||||
private volatile int state=0;
|
|
||||||
public static final int OFFLINE=0;
|
|
||||||
public static final int CONNECTING=1;
|
|
||||||
public static final int ONLINE=2;
|
|
||||||
|
|
||||||
|
|
||||||
private volatile long coolingTime;
|
|
||||||
{
|
|
||||||
resetCoolingTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getState() {
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
public void setState(int state) {
|
|
||||||
this.state = state;
|
|
||||||
}
|
|
||||||
public long getInSpeedMax() {
|
|
||||||
return inSpeedMax;
|
|
||||||
}
|
|
||||||
public void updateLatency(long newlatency) {
|
|
||||||
latencyCurr=newlatency;
|
|
||||||
if(latencyAvg==Long.MIN_VALUE) {
|
|
||||||
latencyAvg=newlatency;
|
|
||||||
}else {
|
|
||||||
long vj=Math.abs( latencyAvg-newlatency);
|
|
||||||
jitter=(9*jitter+vj)/10;
|
|
||||||
/*if(newlatency<latency) {
|
|
||||||
latency=newlatency;
|
|
||||||
}else {*/
|
|
||||||
this.latencyAvg=(latencyAvg*9+ newlatency)/10;
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(latencyMin==Long.MIN_VALUE) {
|
|
||||||
latencyMin=newlatency;
|
|
||||||
}else {
|
|
||||||
/*if(newlatency<latency) {
|
|
||||||
latency=newlatency;
|
|
||||||
}else {*/
|
|
||||||
if(newlatency<=latencyMin) {
|
|
||||||
latencyMin=newlatency;
|
|
||||||
}else {
|
|
||||||
this.latencyMin=(latencyMin*9+ newlatency)/10;
|
|
||||||
}
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public long getOutSpeedMax() {
|
|
||||||
return outSpeedMax;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getInSpeedAvg() {
|
|
||||||
return inSpeedAvg;
|
|
||||||
}
|
|
||||||
public long getOutSpeedAvg() {
|
|
||||||
return outSpeedAvg;
|
|
||||||
}
|
|
||||||
public long getLatencyMin() {
|
|
||||||
return latencyMin;
|
|
||||||
}
|
|
||||||
public long getLatencyCurr() {
|
|
||||||
return latencyCurr;
|
|
||||||
}
|
|
||||||
public long getInTraffic() {
|
|
||||||
return inTraffic.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getOutTraffic() {
|
|
||||||
return outTraffic.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
public AtomicLong getInTrafficAL() {
|
|
||||||
return inTraffic;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getJitter() {
|
|
||||||
return jitter;
|
|
||||||
}
|
|
||||||
public AtomicLong getOutTrafficAL() {
|
|
||||||
return outTraffic;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getInSpeed() {
|
|
||||||
return inSpeed;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public long getOutSpeed() {
|
|
||||||
return outSpeed;
|
|
||||||
}
|
|
||||||
|
|
||||||
private long updatetime=System.nanoTime();
|
|
||||||
public void updateSpeed() {
|
|
||||||
long d=System.nanoTime()-updatetime;
|
|
||||||
long i=inTraffic.get()-inTrafficOld.get();
|
|
||||||
long o=outTraffic.get()-outTrafficOld.get();
|
|
||||||
inTrafficOld.set(inTraffic.get());
|
|
||||||
outTrafficOld.set(outTraffic.get());
|
|
||||||
|
|
||||||
|
|
||||||
inSpeed= i*1000000000/d;
|
|
||||||
outSpeed= o*1000000000/d;
|
|
||||||
updatetime=System.nanoTime();
|
|
||||||
//System.out.println(d+" "+o+" "+i);
|
|
||||||
/*if(inSpeed>inSpeedMax) {
|
|
||||||
inSpeedMax=inSpeed;
|
|
||||||
}else {
|
|
||||||
inSpeedMax=(inSpeedMax*9999+inSpeed)/10000;
|
|
||||||
}
|
|
||||||
if(outSpeed>outSpeedMax) {
|
|
||||||
outSpeedMax=outSpeed;
|
|
||||||
}else {
|
|
||||||
outSpeedMax=(outSpeedMax*9999+outSpeed)/10000;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
this.inSpeedAvg=(inSpeedAvg*9+ inSpeed)/10;
|
|
||||||
this.outSpeedAvg=(outSpeedAvg*9+ outSpeed)/10;
|
|
||||||
|
|
||||||
if(changeListener!=null) {
|
|
||||||
changeListener.accept(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
public void updateOutSpeedMax() {
|
|
||||||
if(outSpeed>outSpeedMax) {
|
|
||||||
outSpeedMax=outSpeed;
|
|
||||||
}else {
|
|
||||||
outSpeedMax=(outSpeedMax*9999+outSpeed)/10000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private Consumer<Monitor>changeListener;
|
|
||||||
|
|
||||||
public Consumer<Monitor> getChangeListener() {
|
|
||||||
return changeListener;
|
|
||||||
}
|
|
||||||
public void setChangeListener(Consumer<Monitor> changeListener) {
|
|
||||||
this.changeListener = changeListener;
|
|
||||||
}
|
|
||||||
public long getLatencyAvg() {
|
|
||||||
return latencyAvg;
|
|
||||||
}
|
|
||||||
public String toString() {
|
|
||||||
StringBuilder sb=new StringBuilder();
|
|
||||||
sb.append(name);
|
|
||||||
sb.append('\t');
|
|
||||||
sb.append(getDsc());
|
|
||||||
sb.append('\t');
|
|
||||||
sb.append(bytesUnit(outTraffic.get())).append("\u2191\t").append(bytesUnit(inTraffic.get())).append("\u2193\t").append(bytesUnit(outSpeed)).append("/s\u2191\t").append(bytesUnit(inSpeed)).append("/s\u2193\t").append(latencyAvg/1000000).append("ms");
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString2() {
|
|
||||||
StringBuilder sb=new StringBuilder();
|
|
||||||
sb.append(name);
|
|
||||||
sb.append('\n');
|
|
||||||
sb.append(getDsc());
|
|
||||||
sb.append('\t');
|
|
||||||
sb.append(bytesUnit(outTraffic.get())).append("\t").append(bytesUnit(inTraffic.get())).append("\t").append(bytesUnit(outSpeed)).append("/s\t").append(bytesUnit(inSpeed)).append("/s\t").append(latencyAvg/1000000).append("ms").append("\t").append(jitter/1000000).append("ms\t");
|
|
||||||
|
|
||||||
if(state==OFFLINE) {
|
|
||||||
sb.append((coolingTime-(System.currentTimeMillis()-mls))/1000L);
|
|
||||||
sb.append('s');
|
|
||||||
}else {
|
|
||||||
sb.append('/');
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.append('\n');
|
|
||||||
sb.append(bytesUnit(outSpeedMax));
|
|
||||||
|
|
||||||
sb.append('\n');
|
|
||||||
sb.append(bytesUnit(inSpeedMax));
|
|
||||||
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
private String getDsc() {
|
|
||||||
switch(state) {
|
|
||||||
case OFFLINE:
|
|
||||||
return "○离线";
|
|
||||||
case CONNECTING:
|
|
||||||
return "◐连接中";
|
|
||||||
case ONLINE:
|
|
||||||
return "●在线";
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
private volatile long mls;
|
|
||||||
public long getCoolingTime() {
|
|
||||||
mls=System.currentTimeMillis();
|
|
||||||
return coolingTime;
|
|
||||||
}
|
|
||||||
public void incCoolingTime() {
|
|
||||||
coolingTime<<=1;
|
|
||||||
if(coolingTime>300000) {
|
|
||||||
coolingTime=300000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public void resetCoolingTime() {
|
|
||||||
coolingTime=10000;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -59,12 +59,12 @@ public class MonitoredInputStream extends FilterInputStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void mark(int readlimit) {
|
public void mark(int readlimit) {
|
||||||
in.mark(readlimit);
|
in.mark(readlimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void reset() throws IOException {
|
public void reset() throws IOException {
|
||||||
in.reset();
|
in.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,24 +9,26 @@ import java.util.TimerTask;
|
|||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
import org.kne.cloud.network.FilterSocket;
|
import org.kne.cloud.network.FilterSocket;
|
||||||
|
import org.kne.cloud.network.monitor.MonitorData;
|
||||||
|
import org.kne.cloud.network.monitor.SpeedAndTrafficMonitorDataImpl;
|
||||||
|
|
||||||
public class MonitoredSocket extends FilterSocket {
|
public class MonitoredSocket extends FilterSocket {
|
||||||
public Monitor getMonitor() {
|
public SpeedAndTrafficMonitorDataImpl getMonitor() {
|
||||||
return monitor;
|
return monitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private Monitor monitor;
|
private SpeedAndTrafficMonitorDataImpl monitor;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void close() throws IOException {
|
public synchronized void close() throws IOException {
|
||||||
super.close();
|
super.close();
|
||||||
}
|
}
|
||||||
public MonitoredSocket(Socket socket) {
|
public MonitoredSocket(Socket socket) {
|
||||||
this(socket,new Monitor());
|
this(socket,new SpeedAndTrafficMonitorDataImpl());
|
||||||
}
|
}
|
||||||
public MonitoredSocket(Socket socket,Monitor monitor) {
|
public MonitoredSocket(Socket socket,SpeedAndTrafficMonitorDataImpl monitor) {
|
||||||
super(socket);
|
super(socket);
|
||||||
this.monitor=monitor;
|
this.monitor=monitor;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,33 +1,39 @@
|
|||||||
package org.kne.cloud.network.klalb;
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
import java.io.DataInput;
|
import java.io.DataInput;
|
||||||
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutput;
|
import java.io.DataOutput;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
public class NACKTPacket extends KLALBPacket implements PortPacket{
|
public class NACKTPacket extends KLALBPacket implements PortPacket{
|
||||||
private int sport,dport;
|
|
||||||
private long number;
|
|
||||||
|
|
||||||
|
|
||||||
public NACKTPacket(int sport,int dport,long number) {
|
public NACKTPacket(int sport,int dport,long number) {
|
||||||
super(NACKT);
|
super(NACKT);
|
||||||
this.sport=sport;
|
header.putInt(sport);
|
||||||
this.dport=dport;
|
header.putInt(dport);
|
||||||
this.number=number;
|
header.putLong(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NACKTPacket() {
|
public NACKTPacket(ByteBuffer bb) {
|
||||||
super(NACKT);
|
super(bb);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "NACKT "+sport+"->"+dport+" "+number+"[]";
|
return "NACKT "+getSport()+"->"+getDport()+" "+getNumber()+"[]";
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSport() {
|
public int getSport() {
|
||||||
return sport;
|
return header.getInt(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getHeaderSize() {
|
||||||
|
return super.getHeaderSize()+17;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -36,28 +42,13 @@ public class NACKTPacket extends KLALBPacket implements PortPacket{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int getDport() {
|
public int getDport() {
|
||||||
return dport;
|
return header.getInt(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getNumber() {
|
public long getNumber() {
|
||||||
return number;
|
return header.getLong(9);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void writeToStream(DataOutput dto) throws IOException {
|
|
||||||
super.writeToStream(dto);
|
|
||||||
dto.writeInt(sport);
|
|
||||||
dto.writeInt(dport);
|
|
||||||
dto.writeLong(number);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void readFromStream(DataInput din) throws IOException {
|
|
||||||
super.readFromStream(din);
|
|
||||||
sport=din.readInt();
|
|
||||||
dport=din.readInt();
|
|
||||||
number=din.readLong();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,41 +1,40 @@
|
|||||||
package org.kne.cloud.network.klalb;
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
import java.io.DataInput;
|
import java.io.DataInput;
|
||||||
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutput;
|
import java.io.DataOutput;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
public class PINGPacket extends KLALBPacket {
|
public class PINGPacket extends KLALBPacket {
|
||||||
|
|
||||||
private long time;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void writeToStream(DataOutput dto) throws IOException {
|
|
||||||
super.writeToStream(dto);
|
|
||||||
dto.writeLong(time);
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getTime() {
|
public long getTime() {
|
||||||
return time;
|
return header.getLong(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void readFromStream(DataInput din) throws IOException {
|
|
||||||
super.readFromStream(din);
|
|
||||||
time=din.readLong();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getLength() {
|
public long getLength() {
|
||||||
return super.getLength()+8;
|
return super.getLength()+8;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PINGPacket() {
|
@Override
|
||||||
super(PING);
|
protected int getHeaderSize() {
|
||||||
|
return super.getHeaderSize()+8;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PINGPacket(long time) {
|
public PINGPacket(long time) {
|
||||||
super(PING);
|
super(PING,-1);
|
||||||
this.time=time;
|
header.putLong(time);
|
||||||
}
|
}
|
||||||
|
public PINGPacket(ByteBuffer bb) {
|
||||||
|
super(bb);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "PING";
|
return "PING";
|
||||||
|
|||||||
@@ -1,55 +1,51 @@
|
|||||||
package org.kne.cloud.network.klalb;
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
import java.io.DataInput;
|
import java.io.DataInput;
|
||||||
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutput;
|
import java.io.DataOutput;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
public class PONGPacket extends KLALBPacket {
|
public class PONGPacket extends KLALBPacket {
|
||||||
|
|
||||||
public long getTimepingsnd() {
|
public long getTimepingsnd() {
|
||||||
return timepingsnd;
|
return header.getLong(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getTimepingrcv() {
|
public long getTimepingrcv() {
|
||||||
return timepingrcv;
|
return header.getLong(9);
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getTimepongsnd() {
|
public long getTimepongsnd() {
|
||||||
return timepongsnd;
|
return header.getLong(17);
|
||||||
}
|
|
||||||
private long timepingsnd,timepingrcv,timepongsnd;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void writeToStream(DataOutput dto) throws IOException {
|
|
||||||
super.writeToStream(dto);
|
|
||||||
dto.writeLong(timepingsnd);
|
|
||||||
dto.writeLong(timepingrcv);
|
|
||||||
dto.writeLong(timepongsnd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void readFromStream(DataInput din) throws IOException {
|
protected int getHeaderSize() {
|
||||||
super.readFromStream(din);
|
return super.getHeaderSize()+24;
|
||||||
timepingsnd=din.readLong();
|
|
||||||
timepingrcv=din.readLong();
|
|
||||||
timepongsnd=din.readLong();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getLength() {
|
public long getLength() {
|
||||||
return super.getLength()+24;
|
return super.getLength()+24;
|
||||||
}
|
}
|
||||||
public PONGPacket() {
|
|
||||||
super(PONG);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PONGPacket( long timepingsnd, long timepingrcv, long timepongsnd) {
|
public PONGPacket( long timepingsnd,long timepingrcv, long timepongsnd) {
|
||||||
super(PONG);
|
super(PONG,-1);
|
||||||
this.timepingsnd = timepingsnd;
|
header.putLong(timepingsnd);
|
||||||
this.timepingrcv = timepingrcv;
|
header.putLong(timepingrcv);
|
||||||
this.timepongsnd = timepongsnd;
|
header.putLong(timepongsnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PONGPacket(ByteBuffer bb) {
|
||||||
|
super(bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "PONG";
|
return "PONG";
|
||||||
|
|||||||
@@ -1,51 +1,47 @@
|
|||||||
package org.kne.cloud.network.klalb;
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
import java.io.DataInput;
|
import java.io.DataInput;
|
||||||
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutput;
|
import java.io.DataOutput;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
public class RSTPacket extends KLALBPacket implements PortPacket{
|
public class RSTPacket extends KLALBPacket implements PortPacket{
|
||||||
private int sport,dport;
|
|
||||||
public RSTPacket(int sport,int dport) {
|
public RSTPacket(int sport,int dport) {
|
||||||
super(RST);
|
super(RST);
|
||||||
this.sport=sport;
|
header.putInt(sport);
|
||||||
this.dport=dport;
|
header.putInt(dport);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RSTPacket(ByteBuffer bb) {
|
||||||
|
super(bb);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getLength() {
|
public long getLength() {
|
||||||
return super.getLength()+8;
|
return super.getLength()+8;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RSTPacket() {
|
@Override
|
||||||
super(RST);
|
protected int getHeaderSize() {
|
||||||
|
return super.getHeaderSize()+8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public int getSport() {
|
public int getSport() {
|
||||||
return sport;
|
return header.getInt(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getDport() {
|
public int getDport() {
|
||||||
return dport;
|
return header.getInt(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "RST "+sport+"->"+dport;
|
return "RST "+getSport()+"->"+getDport();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void writeToStream(DataOutput dto) throws IOException {
|
|
||||||
super.writeToStream(dto);
|
|
||||||
dto.writeInt(sport);
|
|
||||||
dto.writeInt(dport);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void readFromStream(DataInput din) throws IOException {
|
|
||||||
super.readFromStream(din);
|
|
||||||
sport=din.readInt();
|
|
||||||
dport=din.readInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
import java.util.concurrent.atomic.AtomicReferenceArray;
|
||||||
|
|
||||||
|
public class ReceiveSlidingWindow<E> {
|
||||||
|
private AtomicReferenceArray<E> array;
|
||||||
|
private AtomicInteger windowSize =new AtomicInteger();
|
||||||
|
private AtomicLong windowPosition=new AtomicLong();
|
||||||
|
|
||||||
|
public int getWindowSize() {
|
||||||
|
return windowSize.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWindowSize(int windowSize) {
|
||||||
|
this.windowSize.set(windowSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getWindowPosition() {
|
||||||
|
return windowPosition.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWindowPosition(long windowPosition) {
|
||||||
|
this.windowPosition.set(windowPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReceiveSlidingWindow(int capacity){
|
||||||
|
array=new AtomicReferenceArray<E>(capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean push(E object) {
|
||||||
|
Objects.requireNonNull(object);
|
||||||
|
if(array.get((int) ((windowPosition.get()-windowSize.get())%array.length()))==null ) {
|
||||||
|
array.set((int) (windowPosition.getAndIncrement()%array.length()), object);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public E pull(long number) {
|
||||||
|
return array.getAndSet((int) (number%array.length()), null);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
package org.kne.cloud.network.klalb;
|
|
||||||
|
|
||||||
import java.io.DataInput;
|
|
||||||
import java.io.DataOutput;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public class SACKTPacket extends KLALBPacket {
|
|
||||||
@Override
|
|
||||||
public long getLength() {
|
|
||||||
return super.getLength()+8;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSport() {
|
|
||||||
return sport;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getDport() {
|
|
||||||
return dport;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int sport,dport;
|
|
||||||
public SACKTPacket(int sport,int dport) {
|
|
||||||
super(SACKT);
|
|
||||||
this.sport=sport;
|
|
||||||
this.dport=dport;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SACKTPacket() {
|
|
||||||
super(SACKT);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "SACKT "+sport+"->"+dport;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void writeToStream(DataOutput dto) throws IOException {
|
|
||||||
super.writeToStream(dto);
|
|
||||||
dto.writeInt(sport);
|
|
||||||
dto.writeInt(dport);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void readFromStream(DataInput din) throws IOException {
|
|
||||||
super.readFromStream(din);
|
|
||||||
sport=din.readInt();
|
|
||||||
dport=din.readInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
package org.kne.cloud.network.klalb;
|
|
||||||
|
|
||||||
import java.io.DataInput;
|
|
||||||
import java.io.DataOutput;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public class SYNTPacket extends KLALBPacket {
|
|
||||||
private int sport,dport;
|
|
||||||
public SYNTPacket(int sport,int dport) {
|
|
||||||
super(SYNT);
|
|
||||||
this.sport=sport;
|
|
||||||
this.dport=dport;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSport() {
|
|
||||||
return sport;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getDport() {
|
|
||||||
return dport;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SYNTPacket() {
|
|
||||||
super(SYNT);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "SYNT "+sport+"->"+dport;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void writeToStream(DataOutput dto) throws IOException {
|
|
||||||
super.writeToStream(dto);
|
|
||||||
dto.writeInt(sport);
|
|
||||||
dto.writeInt(dport);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getLength() {
|
|
||||||
return super.getLength()+8;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void readFromStream(DataInput din) throws IOException {
|
|
||||||
super.readFromStream(din);
|
|
||||||
sport=din.readInt();
|
|
||||||
dport=din.readInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
import java.util.concurrent.atomic.AtomicReferenceArray;
|
||||||
|
|
||||||
|
public class SendSlidingWindow<E> implements Iterable<E>{
|
||||||
|
private Object[] array;
|
||||||
|
private volatile int windowSize ;
|
||||||
|
private volatile long windowPosition;
|
||||||
|
|
||||||
|
public int getWindowSize() {
|
||||||
|
return windowSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWindowSize(int windowSize) {
|
||||||
|
this.windowSize=windowSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getWindowPosition() {
|
||||||
|
return windowPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWindowPosition(long windowPosition) {
|
||||||
|
this.windowPosition=windowPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SendSlidingWindow(int capacity,int windowSize){
|
||||||
|
if(windowSize>capacity) {
|
||||||
|
throw new IllegalArgumentException("windowSize>capacity!");
|
||||||
|
}
|
||||||
|
array= new Object[capacity];
|
||||||
|
this.windowSize=windowSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean checkPush() {
|
||||||
|
if(array[calcPosition(windowPosition-windowSize)]==null ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void push(E object) {
|
||||||
|
|
||||||
|
array[calcPosition(windowPosition)]= object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public E remove(long number) {
|
||||||
|
if(number<windowPosition&&number>=windowPosition-windowSize) {
|
||||||
|
int indp=calcPosition(number);
|
||||||
|
E old=(E) array[indp];
|
||||||
|
array[indp]=null;
|
||||||
|
return old;
|
||||||
|
}else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty() {
|
||||||
|
for (long i = windowPosition-windowSize; i < windowPosition; i++) {
|
||||||
|
if(array[calcPosition(i)]!=null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public E get(long number) {
|
||||||
|
if(number<windowPosition&&number>=windowPosition-windowSize) {
|
||||||
|
return (E) array[calcPosition(number)];
|
||||||
|
}else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<E> iterator() {
|
||||||
|
return new Iterator<E>() {
|
||||||
|
private long pointer=windowPosition-windowSize;
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return pointer<windowPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E next() {
|
||||||
|
return (E) array[calcPosition(pointer++)];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
private int calcPosition(long number) {
|
||||||
|
return (int) ((number+array.length)%array.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
package org.kne.cloud.network.klalb;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.Inet6Address;
|
|
||||||
import java.net.NoRouteToHostException;
|
|
||||||
import java.util.Timer;
|
|
||||||
import java.util.TimerTask;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
|
|
||||||
public class SendTask {
|
|
||||||
private int maxcount;
|
|
||||||
private AtomicInteger count=new AtomicInteger();
|
|
||||||
private int priority;
|
|
||||||
private Inet6Address address;
|
|
||||||
private volatile long starttime=System.nanoTime();
|
|
||||||
private void resetTime() {
|
|
||||||
starttime=System.nanoTime();
|
|
||||||
}
|
|
||||||
private boolean checkTime(long limit) {
|
|
||||||
long curr=System.nanoTime();
|
|
||||||
boolean b=curr-starttime>limit;
|
|
||||||
if(b)
|
|
||||||
starttime=curr;
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
public SendTask( KLALBController controllker,Inet6Address address,DATATPacket kp,int priority,int maxcount) {
|
|
||||||
super();
|
|
||||||
this.maxcount = maxcount;
|
|
||||||
this.controllker = controllker;
|
|
||||||
this.packet = kp;
|
|
||||||
this.address=address;
|
|
||||||
this.priority=priority;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public KLALBController getControllker() {
|
|
||||||
return controllker;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public DATATPacket getPacket() {
|
|
||||||
return packet;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private KLALBController controllker;
|
|
||||||
private DATATPacket packet;
|
|
||||||
|
|
||||||
|
|
||||||
public int getMaxcount() {
|
|
||||||
return maxcount;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void check(int number) throws IOException {
|
|
||||||
long limit= count.get()*(1000*number+500)*1000000L;
|
|
||||||
if(checkTime(limit))
|
|
||||||
run();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void run() throws IOException {
|
|
||||||
if(count.get()>=maxcount) {
|
|
||||||
throw new IOException("send error!");
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
if(count.get()==0) {
|
|
||||||
controllker.sendPacketToAddress((Inet6Address) address,
|
|
||||||
packet, priority,1);
|
|
||||||
}else {
|
|
||||||
controllker.sendPacketToAddress((Inet6Address) address,
|
|
||||||
packet, priority-1,1);
|
|
||||||
}
|
|
||||||
} catch (NoRouteToHostException e) {
|
|
||||||
}
|
|
||||||
resetTime();
|
|
||||||
count.incrementAndGet();
|
|
||||||
if(count.get()>1) {
|
|
||||||
System.out.println("第"+(count.get()-1)+"次重传:"+packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -18,6 +18,7 @@ import org.kne.cloud.network.SocketToSocketProxy;
|
|||||||
import org.kne.util.AutoProperties;
|
import org.kne.util.AutoProperties;
|
||||||
|
|
||||||
public class SimpleKLALBClient {
|
public class SimpleKLALBClient {
|
||||||
|
public static KLALBStateGUI2 ksg;
|
||||||
public static void main(String[] args) throws UnknownHostException, IOException {
|
public static void main(String[] args) throws UnknownHostException, IOException {
|
||||||
|
|
||||||
System.out.println(CONST.klalb+" V"+CONST.klalbver);
|
System.out.println(CONST.klalb+" V"+CONST.klalbver);
|
||||||
@@ -33,20 +34,41 @@ public static void main(String[] args) throws UnknownHostException, IOException
|
|||||||
MultipurposeSocketAddress vmsa=new MultipurposeSocketAddress("KLALB_Stream",new InetSocketAddress(vad, 23333));
|
MultipurposeSocketAddress vmsa=new MultipurposeSocketAddress("KLALB_Stream",new InetSocketAddress(vad, 23333));
|
||||||
System.out.println("连接成功:"+ap.getProperty("server"));
|
System.out.println("连接成功:"+ap.getProperty("server"));
|
||||||
new SocketToSocketProxy(new MultipurposeSocketAddress(ap.getProperty("local")), vmsa);
|
new SocketToSocketProxy(new MultipurposeSocketAddress(ap.getProperty("local")), vmsa);
|
||||||
System.out.println("提示:输入state并回车可以查看当前线路状态");
|
//System.out.println("提示:输入state并回车可以查看当前线路状态");
|
||||||
while(true) {
|
while(true) {
|
||||||
String s=scn.nextLine();
|
String s=scn.nextLine();
|
||||||
switch(s) {
|
switch(s) {
|
||||||
|
case "help":
|
||||||
|
System.out.println("help:查看命令使用说明");
|
||||||
|
System.out.println("state:查看线路状态");
|
||||||
|
//System.out.println("reload:重新加载线路配置文件");
|
||||||
|
System.out.println("reconnect:所有离线线路跳过重连等待时间立即尝试重连");
|
||||||
|
System.out.println("monitor:显示监视器图形界面");
|
||||||
|
System.out.println("stop:退出程序");
|
||||||
|
break;
|
||||||
|
case "stop":
|
||||||
|
System.exit(0);
|
||||||
|
break;
|
||||||
case "state":
|
case "state":
|
||||||
System.out.println("状态\t上传流量\t下载流量\t上传速度\t下载速度\t延迟\t抖动\t下一次重试");
|
System.out.println("状态\t可靠性\t上传流量\t下载流量\t上传速度\t下载速度\t上传延迟\t下载延迟\t上传抖动\t下载抖动");
|
||||||
|
synchronized (kc.getLines()) {
|
||||||
for (Iterator<KLALBRemoteLine> iterator = kc.getLines().iterator(); iterator.hasNext();) {
|
for (Iterator<KLALBRemoteLine> iterator = kc.getLines().iterator(); iterator.hasNext();) {
|
||||||
KLALBRemoteLine hostPort = iterator.next();
|
KLALBRemoteLine hostPort = iterator.next();
|
||||||
System.out.println(hostPort .toString2());
|
System.out.println(hostPort .toString());
|
||||||
//System.out.println();
|
//System.out.println();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "monitor":
|
||||||
|
if(ksg==null)
|
||||||
|
ksg=new KLALBStateGUI2(kc);
|
||||||
|
ksg.setVisible(true);
|
||||||
|
break;
|
||||||
|
case "reconnect":
|
||||||
|
kc.reconnectImmediately();
|
||||||
break;
|
break;
|
||||||
default :
|
default :
|
||||||
System.out.println("未知命令!");
|
System.out.println("未知命令,请输入help以查询命令说明");
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import org.kne.cloud.network.SocketToSocketProxy;
|
|||||||
import org.kne.cloud.network.SocketType;
|
import org.kne.cloud.network.SocketType;
|
||||||
|
|
||||||
public class SimpleKLALBServer {
|
public class SimpleKLALBServer {
|
||||||
|
public static KLALBStateGUI2 ksg;
|
||||||
public static SocketListener tcpl;
|
public static SocketListener tcpl;
|
||||||
public static DatagramSocketListener udpl;
|
public static DatagramSocketListener udpl;
|
||||||
public static ServerPropties sp;
|
public static ServerPropties sp;
|
||||||
@@ -35,9 +36,9 @@ public class SimpleKLALBServer {
|
|||||||
|
|
||||||
System.out.println("虚拟地址:"+sp.getVirtualIP().getHostAddress());
|
System.out.println("虚拟地址:"+sp.getVirtualIP().getHostAddress());
|
||||||
kc=new KLALBController(sp.getVirtualIP());
|
kc=new KLALBController(sp.getVirtualIP());
|
||||||
kc.setSelflineTableSupplier(()->{
|
/* kc.setSelflineTableSupplier(()->{
|
||||||
return fileRead("linetable.txt");
|
return fileRead("linetable.txt");
|
||||||
});
|
});*/
|
||||||
kc.registerToProxyTypeAs("KLALB");
|
kc.registerToProxyTypeAs("KLALB");
|
||||||
|
|
||||||
System.out.println("开放端口:"+sp.getBind());
|
System.out.println("开放端口:"+sp.getBind());
|
||||||
@@ -53,16 +54,28 @@ public class SimpleKLALBServer {
|
|||||||
String[]sc=s.split(" ");
|
String[]sc=s.split(" ");
|
||||||
switch(sc[0]) {
|
switch(sc[0]) {
|
||||||
case "help":
|
case "help":
|
||||||
System.out.print("state:查看线路状态");
|
System.out.println("state:查看线路状态");
|
||||||
System.out.println("reload:重新加载线路配置");
|
System.out.println("reload:重新加载线路配置");
|
||||||
|
System.out.println("monitor:显示监视器图形界面");
|
||||||
|
System.out.println("stop:退出程序");
|
||||||
break;
|
break;
|
||||||
|
case "stop":
|
||||||
|
System.exit(0);
|
||||||
|
break;
|
||||||
case "state":
|
case "state":
|
||||||
System.out.println("状态\t上传流量\t下载流量\t上传速度\t下载速度\t延迟\t抖动\t下一次重试");
|
System.out.println("状态\t可靠性\t上传流量\t下载流量\t上传速度\t下载速度\t上传延迟\t下载延迟\t上传抖动\t下载抖动");
|
||||||
|
synchronized (kc.getLines()) {
|
||||||
for (Iterator<KLALBRemoteLine> iterator = kc.getLines().iterator(); iterator.hasNext();) {
|
for (Iterator<KLALBRemoteLine> iterator = kc.getLines().iterator(); iterator.hasNext();) {
|
||||||
KLALBRemoteLine hostPort = iterator.next();
|
KLALBRemoteLine hostPort = iterator.next();
|
||||||
System.out.println(hostPort .toString2());
|
System.out.println(hostPort .toString());
|
||||||
//System.out.println();
|
//System.out.println();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "monitor":
|
||||||
|
if(ksg==null)
|
||||||
|
ksg=new KLALBStateGUI2(kc);
|
||||||
|
ksg.setVisible(true);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
System.out.println("未知命令,请输入help以查询指令说明");
|
System.out.println("未知命令,请输入help以查询指令说明");
|
||||||
@@ -120,7 +133,7 @@ public class SimpleKLALBServer {
|
|||||||
udpl.setCon((r)->{
|
udpl.setCon((r)->{
|
||||||
KLALBRemoteLine krl;
|
KLALBRemoteLine krl;
|
||||||
try {
|
try {
|
||||||
krl=new KLALBRemoteLine(new DatagramKLALBPacketLink(r));
|
krl=new KLALBRemoteLine(new SplitedDatagramKLALBPacketLink(r));
|
||||||
kc.addRemoteLine(krl);
|
kc.addRemoteLine(krl);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// TODO 自动生成的 catch 块
|
// TODO 自动生成的 catch 块
|
||||||
|
|||||||
@@ -0,0 +1,322 @@
|
|||||||
|
/*package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.DatagramPacket;
|
||||||
|
import java.net.DatagramSocket;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.SocketException;
|
||||||
|
|
||||||
|
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||||
|
import org.kne.cloud.network.SpeedLimiter;
|
||||||
|
|
||||||
|
public class DatagramKLALBPacketLink implements KLALBPacketLink {
|
||||||
|
|
||||||
|
private static final int MTU=1500;
|
||||||
|
|
||||||
|
private static final int HEAD=32;
|
||||||
|
|
||||||
|
private int packSign=0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return new MultipurposeSocketAddress("UDP",(InetSocketAddress)ds.getLocalSocketAddress())+"←"+new MultipurposeSocketAddress("UDP",(InetSocketAddress)ds.getRemoteSocketAddress());
|
||||||
|
}
|
||||||
|
|
||||||
|
private DatagramSocket ds;
|
||||||
|
|
||||||
|
public DatagramKLALBPacketLink(DatagramSocket connectDatagramSocket) throws IOException {
|
||||||
|
this.ds=connectDatagramSocket;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ByteArrayOutputStream bos=new ByteArrayOutputStream(65535);
|
||||||
|
private DataOutputStream dos=new DataOutputStream(bos);
|
||||||
|
@Override
|
||||||
|
public void writePacket(KLALBPacket kp) throws IOException {
|
||||||
|
//System.out.println(" TX:"+kp);
|
||||||
|
KLALBOutputStream.writeKLALBPacketToStream(dos, kp);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[]bc=new byte[65535];
|
||||||
|
DataInputStream dis;
|
||||||
|
@Override
|
||||||
|
public KLALBPacket readPacket() throws IOException {
|
||||||
|
KLALBPacket kp=null;
|
||||||
|
do {
|
||||||
|
if(dis==null) {
|
||||||
|
|
||||||
|
byte[]data=new byte[65535];
|
||||||
|
DatagramPacket dp=new DatagramPacket(data, data.length);
|
||||||
|
ds.receive(dp);
|
||||||
|
|
||||||
|
|
||||||
|
dis=new DataInputStream(new ByteArrayInputStream(bc, 0, dp.getLength()));
|
||||||
|
}
|
||||||
|
kp=KLALBInputStream.readKLALBPacketFromStream(dis);
|
||||||
|
if(kp!=null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
dis=null;
|
||||||
|
//System.out.println(" RX:"+kp);
|
||||||
|
}while(true);
|
||||||
|
return kp;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
ds.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isClosed() {
|
||||||
|
return ds.isClosed();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSoTimeout(int val) throws SocketException {
|
||||||
|
ds.setSoTimeout(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSoTimeout() throws SocketException {
|
||||||
|
return ds.getSoTimeout();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void flush() throws IOException {
|
||||||
|
byte[]bt=bos.toByteArray();
|
||||||
|
bos.reset();
|
||||||
|
int seq=0;
|
||||||
|
int maxseq=(bt.length+MTU-HEAD-1)/(MTU-HEAD);
|
||||||
|
int startptr=0;
|
||||||
|
while(startptr<bt.length) {
|
||||||
|
int copysize=Math.min(bt.length-startptr,MTU-HEAD);
|
||||||
|
byte[]data=new byte[copysize+4];
|
||||||
|
data[2]=(byte) (packSign>>8);
|
||||||
|
data[3]=(byte) packSign;
|
||||||
|
data[4]=(byte)seq;
|
||||||
|
data[5]=(byte)maxseq;
|
||||||
|
System.arraycopy(bt, startptr, data, 6, copysize);
|
||||||
|
startptr+=copysize;
|
||||||
|
DatagramPacket dp=new DatagramPacket(data,data.length);
|
||||||
|
ds.send(dp);
|
||||||
|
}
|
||||||
|
packSign++;
|
||||||
|
packSign=packSign&0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isStream() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.DatagramPacket;
|
||||||
|
import java.net.DatagramSocket;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.SocketException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.channels.Channels;
|
||||||
|
import java.nio.channels.ReadableByteChannel;
|
||||||
|
import java.nio.channels.WritableByteChannel;
|
||||||
|
|
||||||
|
import org.kne.cloud.network.DatagramServerSocket;
|
||||||
|
import org.kne.cloud.network.DatagramServerSocket.SubDatagramSocket;
|
||||||
|
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||||
|
import org.kne.cloud.network.PacketRebuilder;
|
||||||
|
import org.kne.cloud.network.PacketSpliter;
|
||||||
|
import org.kne.cloud.network.SpeedLimiter;
|
||||||
|
import org.kne.debug.TimeDebugger;
|
||||||
|
|
||||||
|
public class SplitedDatagramKLALBPacketLink implements KLALBPacketLink {
|
||||||
|
private PacketSpliter pslr=new PacketSpliter(65535);
|
||||||
|
private PacketRebuilder pbdr=new PacketRebuilder(1000000000);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return new MultipurposeSocketAddress("UDP",(InetSocketAddress)ds.getLocalSocketAddress())+"←"+new MultipurposeSocketAddress("UDP",(InetSocketAddress)ds.getRemoteSocketAddress());
|
||||||
|
}
|
||||||
|
|
||||||
|
private DatagramSocket ds;
|
||||||
|
|
||||||
|
public SplitedDatagramKLALBPacketLink(DatagramSocket connectDatagramSocket) throws IOException {
|
||||||
|
this.ds=connectDatagramSocket;
|
||||||
|
bibf.limit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ByteBuffer bbf=ByteBuffer.allocate(65535);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writePacket(KLALBPacket kp) throws IOException {
|
||||||
|
//System.out.println(" TX:"+kp);
|
||||||
|
//KLALBPacket.writeKLALBPacketToStream(dos, kp);
|
||||||
|
KLALBPacket.writeKLALBPacketToChannel(new WritableByteChannel() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isOpen() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int write(ByteBuffer src) throws IOException {
|
||||||
|
int sr=src.remaining();
|
||||||
|
//try {
|
||||||
|
bbf.put(src);
|
||||||
|
//}catch (Exception e) {e.printStackTrace();
|
||||||
|
//System.out.println(src+" "+bbf);
|
||||||
|
//}
|
||||||
|
return sr;
|
||||||
|
}
|
||||||
|
|
||||||
|
}, kp);
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[]bc=new byte[65535];
|
||||||
|
|
||||||
|
private ByteBuffer bibf=ByteBuffer.allocate(65535);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KLALBPacket readPacket() throws IOException {
|
||||||
|
KLALBPacket kp=null;
|
||||||
|
do {
|
||||||
|
if(bibf.remaining()<=0) {
|
||||||
|
bibf.clear();
|
||||||
|
|
||||||
|
/*DatagramPacket dp=new DatagramPacket(bc, bc.length);
|
||||||
|
ds.receive(dp);
|
||||||
|
bibf.put(dp.getData(), 0, dp.getLength());*/
|
||||||
|
pbdr.read(bibf,new ReadableByteChannel() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isOpen() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read(ByteBuffer dst) throws IOException {DatagramPacket dp;
|
||||||
|
if(ds instanceof SubDatagramSocket) {
|
||||||
|
dp=((SubDatagramSocket) ds).receive();
|
||||||
|
dst.put(dp.getData(), 0, dp.getLength());
|
||||||
|
|
||||||
|
}else {
|
||||||
|
dp=new DatagramPacket(bc, bc.length);
|
||||||
|
ds.receive(dp);
|
||||||
|
dst.put(dp.getData(), 0, dp.getLength());
|
||||||
|
}
|
||||||
|
return dp.getLength();
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
|
bibf.flip();
|
||||||
|
}
|
||||||
|
kp=KLALBPacket.readKLALBPacketFromChannel(new ReadableByteChannel() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isOpen() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read(ByteBuffer dst) throws IOException {
|
||||||
|
int olmt=bibf.limit();
|
||||||
|
|
||||||
|
int rst=Math.min(bibf.remaining(),dst.remaining());
|
||||||
|
bibf.limit(rst+bibf.position());
|
||||||
|
dst.put(bibf);
|
||||||
|
bibf.limit(olmt);
|
||||||
|
return rst;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if(kp!=null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//dis=null;
|
||||||
|
//System.out.println(" RX:"+kp);
|
||||||
|
}while(true);
|
||||||
|
return kp;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
ds.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isClosed() {
|
||||||
|
return ds.isClosed();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSoTimeout(int val) throws SocketException {
|
||||||
|
ds.setSoTimeout(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSoTimeout() throws SocketException {
|
||||||
|
return ds.getSoTimeout();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void flush() throws IOException {
|
||||||
|
bbf.flip();
|
||||||
|
//TimeDebugger tdb=new TimeDebugger();
|
||||||
|
//tdb.putTime("flushStart");
|
||||||
|
pslr.write(bbf, new WritableByteChannel() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isOpen() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int write(ByteBuffer src) throws IOException {
|
||||||
|
int rem=src.remaining();
|
||||||
|
byte[]bt=src.array();
|
||||||
|
DatagramPacket dp=new DatagramPacket(bt,src.position(),src.limit());
|
||||||
|
ds.send(dp);
|
||||||
|
return rem;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//tdb.putTime("flushEnd");
|
||||||
|
//tdb.print();
|
||||||
|
/*byte[]bt=bbf.array();
|
||||||
|
DatagramPacket dp=new DatagramPacket(bt,bbf.limit());
|
||||||
|
ds.send(dp);*/
|
||||||
|
|
||||||
|
bbf.clear();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isStream() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
|
import java.io.BufferedOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InterruptedIOException;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.ProtocolFamily;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.net.SocketException;
|
||||||
|
import java.net.SocketOption;
|
||||||
|
import java.net.SocketOptions;
|
||||||
|
import java.net.StandardProtocolFamily;
|
||||||
|
import java.net.StandardSocketOptions;
|
||||||
|
import java.nio.Buffer;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.channels.AsynchronousSocketChannel;
|
||||||
|
import java.nio.channels.Channels;
|
||||||
|
import java.nio.channels.SocketChannel;
|
||||||
|
import java.util.Timer;
|
||||||
|
import java.util.TimerTask;
|
||||||
|
|
||||||
|
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||||
|
import org.kne.cloud.network.TimeoutTimer;
|
||||||
|
|
||||||
|
public class StreamChannelKLALBPacketLink implements KLALBPacketLink {
|
||||||
|
private static TimeoutTimer tmoTimer=new TimeoutTimer();
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
try {
|
||||||
|
return new MultipurposeSocketAddress("TCP",(InetSocketAddress)connectSocket.getLocalAddress())+"←"+new MultipurposeSocketAddress("TCP",(InetSocketAddress)connectSocket.getRemoteAddress());
|
||||||
|
} catch (IOException e) {
|
||||||
|
return "?←?";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private SocketChannel connectSocket;
|
||||||
|
private int sotimeout;
|
||||||
|
public StreamChannelKLALBPacketLink(SocketChannel connectSocket) throws IOException {
|
||||||
|
this.connectSocket=connectSocket;
|
||||||
|
new KLALBOutputStream(Channels.newOutputStream(connectSocket));
|
||||||
|
new KLALBInputStream(Channels.newInputStream(connectSocket));
|
||||||
|
connectSocket.setOption(StandardSocketOptions.TCP_NODELAY,true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writePacket(KLALBPacket kp) throws IOException {
|
||||||
|
KLALBPacket.writeKLALBPacketToChannel(connectSocket, kp);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KLALBPacket readPacket() throws IOException {
|
||||||
|
TimerTask tsk= tmoTimer.createTimeOutTask(connectSocket, sotimeout);
|
||||||
|
KLALBPacket res;
|
||||||
|
try {
|
||||||
|
res=KLALBPacket.readKLALBPacketFromChannel(connectSocket);
|
||||||
|
}finally {
|
||||||
|
if(tsk!=null)
|
||||||
|
tsk.cancel();
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
connectSocket.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isClosed() {
|
||||||
|
return !connectSocket.isOpen();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSoTimeout(int val) throws SocketException {
|
||||||
|
sotimeout=val;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSoTimeout() throws SocketException {
|
||||||
|
return sotimeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void flush() throws IOException {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isStream() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -3,15 +3,18 @@ package org.kne.cloud.network.klalb;
|
|||||||
import java.io.BufferedOutputStream;
|
import java.io.BufferedOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
import java.nio.Buffer;
|
import java.nio.Buffer;
|
||||||
|
|
||||||
|
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||||
|
|
||||||
public class StreamKLALBPacketLink implements KLALBPacketLink {
|
public class StreamKLALBPacketLink implements KLALBPacketLink {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "StreamKLALBPacketLink [connectSocket=" + connectSocket + "]";
|
return new MultipurposeSocketAddress("TCP",(InetSocketAddress)connectSocket.getLocalSocketAddress())+"←"+new MultipurposeSocketAddress("TCP",(InetSocketAddress)connectSocket.getRemoteSocketAddress());
|
||||||
}
|
}
|
||||||
|
|
||||||
private Socket connectSocket;
|
private Socket connectSocket;
|
||||||
@@ -30,7 +33,7 @@ public class StreamKLALBPacketLink implements KLALBPacketLink {
|
|||||||
public void writePacket(KLALBPacket kp) throws IOException {
|
public void writePacket(KLALBPacket kp) throws IOException {
|
||||||
out.writePacket(kp);
|
out.writePacket(kp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KLALBPacket readPacket() throws IOException {
|
public KLALBPacket readPacket() throws IOException {
|
||||||
return in.readPacket();
|
return in.readPacket();
|
||||||
@@ -56,4 +59,14 @@ public class StreamKLALBPacketLink implements KLALBPacketLink {
|
|||||||
return connectSocket.getSoTimeout();
|
return connectSocket.getSoTimeout();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void flush() throws IOException {
|
||||||
|
out.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isStream() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,25 @@
|
|||||||
package org.kne.cloud.network.klalb;
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
import java.io.DataInput;
|
import java.io.DataInput;
|
||||||
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutput;
|
import java.io.DataOutput;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.channels.ReadableByteChannel;
|
||||||
|
import java.nio.channels.WritableByteChannel;
|
||||||
|
|
||||||
public class TESTPacket extends KLALBPacket {
|
public class TESTPacket extends KLALBPacket {
|
||||||
private static byte[]K=new byte[1024];
|
private static ByteBuffer K=ByteBuffer.allocateDirect(1024);
|
||||||
@Override
|
@Override
|
||||||
public long getLength() {
|
public long getLength() {
|
||||||
return super.getLength()+1024;
|
return super.getLength()+K.limit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getHeaderSize() {
|
||||||
|
return super.getHeaderSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -18,20 +29,29 @@ public class TESTPacket extends KLALBPacket {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||||
|
super.writeToChannel(dto);
|
||||||
|
dto.write(K.slice());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void readFromChannel(ReadableByteChannel din) throws IOException {
|
||||||
|
super.readFromChannel(din);
|
||||||
|
din.read(K.slice());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public TESTPacket(ByteBuffer bb) {
|
||||||
|
super(bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "TEST";
|
return "TEST";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void writeToStream(DataOutput dto) throws IOException {
|
|
||||||
super.writeToStream(dto);
|
|
||||||
dto.write(K);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void readFromStream(DataInput din) throws IOException {
|
|
||||||
super.readFromStream(din);
|
|
||||||
din.readFully(K, 0, K.length);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import java.awt.Color;
|
|||||||
import javax.swing.SwingConstants;
|
import javax.swing.SwingConstants;
|
||||||
import javax.swing.border.LineBorder;
|
import javax.swing.border.LineBorder;
|
||||||
|
|
||||||
|
import org.kne.cloud.network.monitor.MonitorData;
|
||||||
|
|
||||||
import java.awt.Font;
|
import java.awt.Font;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@@ -50,11 +52,7 @@ public class TPanel extends JPanel {
|
|||||||
setLayout(new BorderLayout(0, 0));
|
setLayout(new BorderLayout(0, 0));
|
||||||
|
|
||||||
tname = new JLabel();
|
tname = new JLabel();
|
||||||
if(t.getSocketAddress()!=null) {
|
tname.setText(t.getMonitor().getName());
|
||||||
tname.setText(t.getSocketAddress().toString());
|
|
||||||
}else {
|
|
||||||
tname.setText(t.getKplink().toString());
|
|
||||||
}
|
|
||||||
tname.setFont(new Font("宋体", Font.BOLD, 16));
|
tname.setFont(new Font("宋体", Font.BOLD, 16));
|
||||||
add(tname, BorderLayout.WEST);
|
add(tname, BorderLayout.WEST);
|
||||||
|
|
||||||
@@ -108,13 +106,13 @@ public class TPanel extends JPanel {
|
|||||||
|
|
||||||
public void updateTraffic() {
|
public void updateTraffic() {
|
||||||
switch (tunnel.getMonitor().getState()) {
|
switch (tunnel.getMonitor().getState()) {
|
||||||
case Monitor.OFFLINE:
|
case MonitorData.OFFLINE:
|
||||||
tname.setForeground(Color.RED);
|
tname.setForeground(Color.RED);
|
||||||
break;
|
break;
|
||||||
case Monitor.CONNECTING:
|
case MonitorData.CONNECTING:
|
||||||
tname.setForeground(Color.YELLOW);
|
tname.setForeground(Color.YELLOW);
|
||||||
break;
|
break;
|
||||||
case Monitor.ONLINE:
|
case MonitorData.ONLINE:
|
||||||
tname.setForeground(Color.GREEN);
|
tname.setForeground(Color.GREEN);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -124,7 +122,7 @@ public class TPanel extends JPanel {
|
|||||||
down = tunnel.getMonitor().getInTraffic();
|
down = tunnel.getMonitor().getInTraffic();
|
||||||
this.ups = tunnel.getMonitor().getOutSpeed();
|
this.ups = tunnel.getMonitor().getOutSpeed();
|
||||||
this.downs = tunnel.getMonitor().getInSpeed();
|
this.downs = tunnel.getMonitor().getInSpeed();
|
||||||
this.delay = tunnel.getMonitor().getLatencyAvg();
|
this.delay = tunnel.getMonitor().getLatency();
|
||||||
//System.out.println(delay);
|
//System.out.println(delay);
|
||||||
updateText();
|
updateText();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,350 @@
|
|||||||
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import java.awt.BorderLayout;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
|
||||||
|
import javax.swing.SwingConstants;
|
||||||
|
import javax.swing.border.LineBorder;
|
||||||
|
|
||||||
|
import org.kne.cloud.network.monitor.MonitorData;
|
||||||
|
|
||||||
|
import java.awt.Font;
|
||||||
|
import java.awt.Image;
|
||||||
|
import java.awt.Toolkit;
|
||||||
|
import java.awt.datatransfer.StringSelection;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.awt.event.MouseListener;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.Inet6Address;
|
||||||
|
import java.net.SocketTimeoutException;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import javax.swing.ImageIcon;
|
||||||
|
import javax.swing.JPopupMenu;
|
||||||
|
import javax.swing.JMenuItem;
|
||||||
|
|
||||||
|
public class TPanel2 extends JPanel {
|
||||||
|
private JLabel tname;
|
||||||
|
private JLabel targup;
|
||||||
|
private KLALBRemoteLine tunnel;
|
||||||
|
private LineMonitorGUI mdg;
|
||||||
|
private JMenuItem mntmNewMenuItem2;
|
||||||
|
private JMenuItem mntmNewMenuItem3;
|
||||||
|
private static volatile Image imgup,imgdown,imgeth;
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(tunnel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
TPanel2 other = (TPanel2) obj;
|
||||||
|
return Objects.equals(tunnel, other.tunnel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public JLabel getTname() {
|
||||||
|
return tname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JLabel getTarg() {
|
||||||
|
return targup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @wbp.parser.constructor
|
||||||
|
*/
|
||||||
|
public TPanel2(KLALBRemoteLine t) {
|
||||||
|
this.tunnel = t;
|
||||||
|
//setOpaque(false);
|
||||||
|
setBackground(Color.WHITE);
|
||||||
|
setLayout(new BorderLayout(0, 0));
|
||||||
|
|
||||||
|
tname = new JLabel();
|
||||||
|
tname.setText(t.getMonitor().getName());
|
||||||
|
tname.setFont(new Font("宋体", Font.BOLD, 16));
|
||||||
|
|
||||||
|
targup = new JLabel();
|
||||||
|
try {
|
||||||
|
targup.setIcon(new ImageIcon(getImgUp() ));
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
targup.setFont(new Font("宋体", Font.PLAIN, 13));
|
||||||
|
targup.setHorizontalAlignment(SwingConstants.TRAILING);
|
||||||
|
targup.setForeground(Color.BLACK);
|
||||||
|
targup.setHorizontalTextPosition(SwingConstants.LEFT);
|
||||||
|
|
||||||
|
setBorder(new LineBorder(Color.LIGHT_GRAY));
|
||||||
|
setSize(720, 45);
|
||||||
|
setPreferredSize(getSize());
|
||||||
|
|
||||||
|
JPanel panel = new JPanel();
|
||||||
|
panel.setOpaque(false);
|
||||||
|
add(panel, BorderLayout.CENTER);
|
||||||
|
panel.setLayout(new BorderLayout(0, 0));
|
||||||
|
panel.add(tname);
|
||||||
|
|
||||||
|
vaddr = new JLabel("unknown");
|
||||||
|
panel.add(vaddr, BorderLayout.SOUTH);
|
||||||
|
vaddr.setForeground(Color.DARK_GRAY);
|
||||||
|
|
||||||
|
panel_1 = new JPanel();
|
||||||
|
panel_1.setOpaque(false);
|
||||||
|
add(panel_1, BorderLayout.EAST);
|
||||||
|
panel_1.setLayout(new BorderLayout(0, 0));
|
||||||
|
panel_1.add(targup, BorderLayout.NORTH);
|
||||||
|
|
||||||
|
targdown = new JLabel();
|
||||||
|
try {
|
||||||
|
targdown.setIcon(new ImageIcon(getImgDown()));
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
targdown.setHorizontalTextPosition(SwingConstants.LEFT);
|
||||||
|
targdown.setFont(new Font("宋体", Font.PLAIN, 13));
|
||||||
|
targdown.setHorizontalAlignment(SwingConstants.TRAILING);
|
||||||
|
targdown.setForeground(Color.BLACK);
|
||||||
|
panel_1.add(targdown, BorderLayout.SOUTH);
|
||||||
|
|
||||||
|
|
||||||
|
panel_2 = new JPanel();
|
||||||
|
panel_2.setOpaque(false);
|
||||||
|
panel_2.setPreferredSize(new Dimension(50, 45));
|
||||||
|
panel_2.setSize(panel_2.getPreferredSize());
|
||||||
|
add(panel_2, BorderLayout.WEST);
|
||||||
|
panel_2.setLayout(null);
|
||||||
|
|
||||||
|
lblNewLabel = new JLabel();
|
||||||
|
lblNewLabel.setBounds(0, 0, 50, 45);
|
||||||
|
panel_2.add(lblNewLabel);
|
||||||
|
try {
|
||||||
|
lblNewLabel.setIcon(new ImageIcon(getImgEth()));
|
||||||
|
} catch (IOException e1) {
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
lblNewLabel_1 = new JLabel();
|
||||||
|
lblNewLabel_1.setOpaque(true);
|
||||||
|
lblNewLabel_1.setBackground(Color.LIGHT_GRAY);
|
||||||
|
lblNewLabel_1.setBounds(6, 9, 7, 4);
|
||||||
|
panel_2.add(lblNewLabel_1);
|
||||||
|
|
||||||
|
lblNewLabel_2 = new JLabel();
|
||||||
|
lblNewLabel_2.setOpaque(true);
|
||||||
|
lblNewLabel_2.setBackground(Color.LIGHT_GRAY);
|
||||||
|
lblNewLabel_2.setBounds(35, 9, 7, 4);
|
||||||
|
panel_2.add(lblNewLabel_2);
|
||||||
|
|
||||||
|
|
||||||
|
popupMenu = new JPopupMenu();
|
||||||
|
|
||||||
|
mntmNewMenuItem = new JMenuItem("View line monitor");
|
||||||
|
popupMenu.add(mntmNewMenuItem);
|
||||||
|
mntmNewMenuItem.addActionListener(new ActionListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
|
||||||
|
mdg.setVisible(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
JMenuItem mntmNewMenuItemz = new JMenuItem("Copy line address");
|
||||||
|
popupMenu.add(mntmNewMenuItemz);
|
||||||
|
mntmNewMenuItemz.addActionListener(new ActionListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(tname.getText()), null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
JMenuItem mntmNewMenuItemx = new JMenuItem("Copy virtual address");
|
||||||
|
popupMenu.add(mntmNewMenuItemx);
|
||||||
|
mntmNewMenuItemx.addActionListener(new ActionListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
|
||||||
|
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(vaddr.getText()), null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
mntmNewMenuItem2 = new JMenuItem("Force disconnect");
|
||||||
|
popupMenu.add(mntmNewMenuItem2);
|
||||||
|
mntmNewMenuItem2.addActionListener(new ActionListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
tunnel.dislink();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
mntmNewMenuItem2.setForeground(Color.RED);
|
||||||
|
|
||||||
|
mntmNewMenuItem3 = new JMenuItem("Force reconnect");
|
||||||
|
popupMenu.add(mntmNewMenuItem3);
|
||||||
|
mntmNewMenuItem3.addActionListener(new ActionListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
tunnel.reconnectImmediately();
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
mntmNewMenuItem3.setForeground(Color.GREEN);
|
||||||
|
|
||||||
|
mdg=new LineMonitorGUI(t);
|
||||||
|
addMouseListener(new MouseListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseReleased(MouseEvent e) {
|
||||||
|
if(e.isPopupTrigger())
|
||||||
|
popupMenu.show(TPanel2.this,e.getX(),e.getY());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
// TODO 自动生成的方法存根
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseExited(MouseEvent e) {
|
||||||
|
// TODO 自动生成的方法存根
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseEntered(MouseEvent e) {
|
||||||
|
// TODO 自动生成的方法存根
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseClicked(MouseEvent e) {
|
||||||
|
switch(e.getButton()) {
|
||||||
|
case MouseEvent.BUTTON1:
|
||||||
|
if(e.getClickCount()==2) {
|
||||||
|
mdg.setVisible(true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MouseEvent.BUTTON3:
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Image getImgEth() throws IOException {
|
||||||
|
if(imgeth==null) {
|
||||||
|
imgeth=ImageIO.read(TPanel2.class.getResourceAsStream("/assets/ethnet.png"));
|
||||||
|
}
|
||||||
|
return imgeth;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Image getImgUp() throws IOException {
|
||||||
|
if(imgup==null) {
|
||||||
|
imgup=ImageIO.read(TPanel2.class.getResourceAsStream("/assets/KLALBupload.png")).getScaledInstance(20, 20,Image.SCALE_SMOOTH);
|
||||||
|
}
|
||||||
|
return imgup;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Image getImgDown() throws IOException {
|
||||||
|
if(imgdown==null) {
|
||||||
|
imgdown=ImageIO.read(TPanel2.class.getResourceAsStream("/assets/KLALBdownload.png")).getScaledInstance(20, 20,Image.SCALE_SMOOTH);
|
||||||
|
}
|
||||||
|
return imgdown;
|
||||||
|
}
|
||||||
|
|
||||||
|
private JLabel vaddr;
|
||||||
|
private JPanel panel_1;
|
||||||
|
private JLabel targdown;
|
||||||
|
private JPanel panel_2;
|
||||||
|
private JPopupMenu popupMenu;
|
||||||
|
private JMenuItem mntmNewMenuItem;
|
||||||
|
private JLabel lblNewLabel;
|
||||||
|
private JLabel lblNewLabel_1;
|
||||||
|
private JLabel lblNewLabel_2;
|
||||||
|
|
||||||
|
|
||||||
|
private void updateText() {
|
||||||
|
targup.setText(KLALBUtils. bytesUnit(tunnel.getMonitor().getOutTraffic()) + "\u2191 " + KLALBUtils. bytesUnit(tunnel.getMonitor().getOutSpeed()) + "/s\u2191 "+ String.format("%.1f", tunnel.getMonitor().getOutDelay()/1000000.0) + "ms");
|
||||||
|
targdown.setText(KLALBUtils. bytesUnit(tunnel.getMonitor().getInTraffic()) + "\u2193 " + KLALBUtils. bytesUnit(tunnel.getMonitor().getInSpeed()) + "/s\u2193 " + String.format("%.1f", tunnel.getMonitor().getInDelay()/1000000.0) + "ms");
|
||||||
|
|
||||||
|
if(tunnel.getMonitor().getOutSpeed()>2048||tunnel.getMonitor().getInSpeed()>2048) {
|
||||||
|
lblNewLabel_2.setBackground(Color.ORANGE);
|
||||||
|
}else {
|
||||||
|
lblNewLabel_2.setBackground(Color.LIGHT_GRAY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public KLALBRemoteLine getTunnel() {
|
||||||
|
return tunnel;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String bytesUnit(long v) {
|
||||||
|
if (v >= 1024L * 1024 * 1024 * 1024 * 1024) {
|
||||||
|
return String.format("%.1f", v / (1024.0 * 1024.0 * 1024.0 * 1024.0 * 1024.0)) + "PB";
|
||||||
|
} else if (v >= 1024L * 1024 * 1024 * 1024) {
|
||||||
|
return String.format("%.1f", v / (1024.0 * 1024.0 * 1024.0 * 1024.0)) + "TB";
|
||||||
|
} else if (v >= 1024L * 1024 * 1024) {
|
||||||
|
return String.format("%.1f", v / (1024.0 * 1024.0 * 1024.0)) + "GB";
|
||||||
|
} else if (v >= 1024L * 1024) {
|
||||||
|
return String.format("%.1f", v / (1024.0 * 1024.0)) + "MB";
|
||||||
|
} else if (v >= 1024L) {
|
||||||
|
return String.format("%.1f", v / (1024.0)) + "KB";
|
||||||
|
} else {
|
||||||
|
return v + "B";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateTraffic() {
|
||||||
|
switch (tunnel.getMonitor().getState()) {
|
||||||
|
case MonitorData.OFFLINE:
|
||||||
|
tname.setForeground(Color.RED);
|
||||||
|
lblNewLabel_1.setBackground(Color.LIGHT_GRAY);
|
||||||
|
break;
|
||||||
|
case MonitorData.CONNECTING:
|
||||||
|
tname.setForeground(Color.YELLOW);
|
||||||
|
lblNewLabel_1.setBackground(Color.LIGHT_GRAY);
|
||||||
|
break;
|
||||||
|
case MonitorData.ONLINE:
|
||||||
|
tname.setForeground(Color.GREEN);
|
||||||
|
lblNewLabel_1.setBackground(Color.GREEN);
|
||||||
|
|
||||||
|
|
||||||
|
Inet6Address unvar=tunnel.getRemoteVaddr();
|
||||||
|
if(unvar==null) {
|
||||||
|
this.vaddr.setText("unknown");
|
||||||
|
}else {
|
||||||
|
this.vaddr.setText(unvar.getHostAddress());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
updateText();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//mdg.updateTraffic();
|
||||||
|
}
|
||||||
|
|
||||||
|
public LineMonitorGUI getMdg() {
|
||||||
|
return mdg;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,11 +1,17 @@
|
|||||||
package org.kne.cloud.network.klalb;
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
public class VADDRACKPacket extends KLALBPacket {
|
public class VADDRACKPacket extends KLALBPacket {
|
||||||
|
|
||||||
public VADDRACKPacket() {
|
public VADDRACKPacket() {
|
||||||
super(VADDRACK);
|
super(VADDRACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public VADDRACKPacket(ByteBuffer bb) {
|
||||||
|
super(bb);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "VADDRACK";
|
return "VADDRACK";
|
||||||
|
|||||||