diff --git a/.classpath b/.classpath
index 407aa40..7155ec1 100644
--- a/.classpath
+++ b/.classpath
@@ -10,5 +10,7 @@
+
+
diff --git a/KLALB协议规范V2.3.docx b/KLALB协议规范V2.3.docx
new file mode 100644
index 0000000..09f1293
Binary files /dev/null and b/KLALB协议规范V2.3.docx differ
diff --git a/klalbclient.ini b/klalbclient.ini
new file mode 100644
index 0000000..e69de29
diff --git a/klalbconfig.json b/klalbconfig.json
index eeca17c..99629f9 100644
--- a/klalbconfig.json
+++ b/klalbconfig.json
@@ -1,29 +1,79 @@
[
{"Type":"KLALBController" ,
- "TCPListen" : "0.0.0.0:4567",
+ "TCPListen" : "0.0.0.0:4565",
+ "UDPListen" : "{UDP}0.0.0.0:4572",
"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" ,
- "Listen" : "0.0.0.0:4569",
+ "Listen" : "0.0.0.0:4572",
+"Bridge":{
+ "KLALB" : "SocketBridge",
+ "RDP":"SocketBridge",
+ "HTTP":"SocketBridge",
+ "HTTPS":"SocketBridge",
+ "DEFAULT":"MinecraftSocketBridge23332"
+ } ,
"Connect" : {
- "KLALB" : "127.0.0.1:4567",
+ "KLALB" : "127.0.0.1:4565",
"RDP":"127.0.0.1:3389",
"HTTP":"127.0.0.1:5212",
"HTTPS":"192.168.1.235:443",
- "DEFAULT":"127.0.0.1:36554"
+ "DEFAULT":"127.0.0.1:36555"
}
},
- {"Type":"MinecraftSocketBridge" ,
- "Listen" : "0.0.0.0:36554",
- "Connect" : "127.0.0.1:36555"
- },
- {"Type":"MinecraftSocketBridge" ,
+ {"Type":"SocketBridge" ,
"Listen" : "{KLALB_Stream}[::0]:23332",
+"Bridge":"MinecraftSocketBridge23332",
"Connect" : "127.0.0.1:36555"
},
{ "Type":"SocketBridge" ,
"Listen" : "{KLALB_Stream}[::0]:23333",
+"Bridge":"SocketBridge",
"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"
}
]
\ No newline at end of file
diff --git a/lib/JFreeChart1.5.2.jar b/lib/JFreeChart1.5.2.jar
new file mode 100644
index 0000000..1cb0ee2
Binary files /dev/null and b/lib/JFreeChart1.5.2.jar differ
diff --git a/lib/ini4j.jar b/lib/ini4j.jar
index c2fc538..53d5715 100644
Binary files a/lib/ini4j.jar and b/lib/ini4j.jar differ
diff --git a/lib/toml4j-0.7.1.jar b/lib/toml4j-0.7.1.jar
new file mode 100644
index 0000000..d97341a
Binary files /dev/null and b/lib/toml4j-0.7.1.jar differ
diff --git a/linetable.txt b/linetable.txt
index d11d069..e69de29 100644
--- a/linetable.txt
+++ b/linetable.txt
@@ -1,2 +0,0 @@
-{UDP}192.168.1.233:4569
-{UDP}192.168.0.233:4569
\ No newline at end of file
diff --git a/src/assets/KLALBdownload.png b/src/assets/KLALBdownload.png
new file mode 100644
index 0000000..8393ed2
Binary files /dev/null and b/src/assets/KLALBdownload.png differ
diff --git a/src/assets/KLALBupload.png b/src/assets/KLALBupload.png
new file mode 100644
index 0000000..daf455f
Binary files /dev/null and b/src/assets/KLALBupload.png differ
diff --git a/src/assets/close.png b/src/assets/close.png
index 5163cb0..4aa652d 100644
Binary files a/src/assets/close.png and b/src/assets/close.png differ
diff --git a/src/assets/ethnet.png b/src/assets/ethnet.png
new file mode 100644
index 0000000..8d20296
Binary files /dev/null and b/src/assets/ethnet.png differ
diff --git a/src/assets/maxium.png b/src/assets/maxium.png
index 918a2ba..94fd6aa 100644
Binary files a/src/assets/maxium.png and b/src/assets/maxium.png differ
diff --git a/src/assets/minium.png b/src/assets/minium.png
index 830af78..41b38cd 100644
Binary files a/src/assets/minium.png and b/src/assets/minium.png differ
diff --git a/src/org/kne/cloud/clock/AdjustedNanoClock.java b/src/org/kne/cloud/clock/AdjustedNanoClock.java
new file mode 100644
index 0000000..ff38f9a
--- /dev/null
+++ b/src/org/kne/cloud/clock/AdjustedNanoClock.java
@@ -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;
+ }
+ }
+}
diff --git a/src/org/kne/cloud/clock/ExponentialBackoffTimeClock.java b/src/org/kne/cloud/clock/ExponentialBackoffTimeClock.java
new file mode 100644
index 0000000..4bc630e
--- /dev/null
+++ b/src/org/kne/cloud/clock/ExponentialBackoffTimeClock.java
@@ -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;
+ }
+}
diff --git a/src/org/kne/cloud/clock/ReliabilityBackoffTimeClock.java b/src/org/kne/cloud/clock/ReliabilityBackoffTimeClock.java
new file mode 100644
index 0000000..0e54db5
--- /dev/null
+++ b/src/org/kne/cloud/clock/ReliabilityBackoffTimeClock.java
@@ -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);
+ }
+}
diff --git a/src/org/kne/cloud/network/DatagramServerSocket.java b/src/org/kne/cloud/network/DatagramServerSocket.java
index 54a5ba7..15d6486 100644
--- a/src/org/kne/cloud/network/DatagramServerSocket.java
+++ b/src/org/kne/cloud/network/DatagramServerSocket.java
@@ -7,170 +7,359 @@ import java.net.DatagramSocket;
import java.net.DatagramSocketImpl;
import java.net.InetAddress;
import java.net.InetSocketAddress;
+import java.net.NetworkInterface;
+import java.net.ServerSocket;
import java.net.SocketAddress;
import java.net.SocketException;
+import java.net.SocketTimeoutException;
import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Flow.Subscriber;
+import java.util.concurrent.locks.LockSupport;
-public class DatagramServerSocket extends DatagramSocket {
- private Map clients=new ConcurrentHashMap<>();
+import org.kne.cloud.network.klalb.ByteArrayPool;
+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 skts=new HashSet<>();
+ private final Object stateLock = new Object();
+ private BlockingQueue recs;
+ private InetSocketAddress bindpoint;
+
+
+
+
+
public DatagramServerSocket() throws SocketException {
- super((SocketAddress)null);
- setReuseAddress(true);
+ this(new DefaultDatagramSocketFactory());
}
- protected DatagramServerSocket(DatagramSocketImpl impl) throws SocketException {
- super(impl);
- setReuseAddress(true);
+ protected DatagramServerSocket(DatagramSocketFactory impl) throws SocketException {
+ this.dgsf=impl;
}
public DatagramServerSocket(int port, InetAddress laddr) throws SocketException {
- super((SocketAddress)null);
- setReuseAddress(true);
+ this(new DefaultDatagramSocketFactory());
bind(new InetSocketAddress(laddr, port));
}
public DatagramServerSocket(int port) throws SocketException {
- super((SocketAddress)null);
- setReuseAddress(true);
+ this(new DefaultDatagramSocketFactory());
bind(new InetSocketAddress(port));
}
public DatagramServerSocket(SocketAddress bindaddr) throws SocketException {
- super((SocketAddress)null);
- setReuseAddress(true);
+ this(new DefaultDatagramSocketFactory());
bind(bindaddr);
}
public DatagramServerSocket(int port, int backlog) throws SocketException {
- super((SocketAddress)null);
- setReuseAddress(true);
+ this(new DefaultDatagramSocketFactory());
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 {
- super((SocketAddress)null);
- setReuseAddress(true);
+ this(new DefaultDatagramSocketFactory());
bind(new InetSocketAddress(laddr, port));
}
- public DatagramSocket accept()throws IOException{
- if (isClosed())
+ public void bind(SocketAddress endpoint) throws SocketException {
+ bind(endpoint, 50);
+ }
+ public void bind(SocketAddress endpoint, int backlog) throws SocketException {
+ if (isClosed())
throw new SocketException("Socket is closed");
- if (!isBound())
- throw new SocketException("Socket is not bound yet");
- DatagramPacket dp=new DatagramPacket(new byte[65535], 65535);
- do {
- receive(dp);
- System.out.println(dp);
- }while(clients.containsKey(dp.getSocketAddress()));
- System.out.println("accept");
- SubDatagramSocket re=new SubDatagramSocket((SocketAddress)null);
- re.dp=dp;
- re.setReuseAddress(true);
- re.bind(new InetSocketAddress(InetAddress.getByName("192.168.0.233"), getLocalPort()));
- re.connect(dp.getSocketAddress());
- return re;
- /* loop:while(true) {
- receive(dp);
- SocketAddress isa= dp.getSocketAddress() ;
- synchronized (clients) {
- for (Iterator iterator = clients.iterator(); iterator.hasNext();) {
- SubDatagramSocket subDatagramSocket = (SubDatagramSocket) iterator.next();
- if(subDatagramSocket.getRemoteSocketAddress().equals(isa)) {
- DatagramPacket dpx=dp;
- dp=new DatagramPacket(new byte[65535], 65535);
- subDatagramSocket.getFstq().offer(dpx);
- continue loop;
+ if (isBound())
+ throw new SocketException("Already bound");
+ if (endpoint == null)
+ endpoint = new InetSocketAddress(0);
+ if (!(endpoint instanceof InetSocketAddress epoint))
+ throw new IllegalArgumentException("Unsupported address type");
+ if (epoint.isUnresolved())
+ throw new SocketException("Unresolved address");
+ if (backlog < 1)
+ backlog = 50;
+
+ @SuppressWarnings("removal")
+ SecurityManager security = System.getSecurityManager();
+ if (security != null)
+ security.checkListen(epoint.getPort());
+
+ synchronized (stateLock) {
+ if (closed)
+ throw new SocketException("Socket is closed");
+ if (bound)
+ throw new SocketException("Already bound");
+ bind0(epoint);
+ recs=new ArrayBlockingQueue(backlog);
+ bound = true;
+ }
+ }
+
+
+ private void bind0(InetSocketAddress epoint) throws SocketException {
+ bindpoint=epoint;
+ if(epoint.getAddress().isAnyLocalAddress()) {
+ Enumerationeu= NetworkInterface.getNetworkInterfaces();
+ while (eu.hasMoreElements()) {
+ NetworkInterface networkInterface = (NetworkInterface) eu.nextElement();
+ if(networkInterface.isUp()) {
+ //System.out.println(networkInterface+" "+networkInterface.isUp());
+ Enumerationei= 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);
- SubDatagramSocket sds=new SubDatagramSocket(isa);
- sds.getFstq().add(dpx);
- return sds;
-
- }
- }*/
+
+ }else {
+ DatagramDistributor dd=new DatagramDistributor(epoint);
+ skts.add(dd);
+ }
}
- private class SubDatagramSocket extends DatagramSocket{
+ private class DatagramDistributor implements Runnable{
+ private Map clients=new ConcurrentHashMap<>();
- DatagramPacket dp;
-
- public SubDatagramSocket() throws SocketException {
- super();
+ private InetSocketAddress epoint;
+ private DatagramSocket datagramSocket;
+ public DatagramDistributor(InetSocketAddress epoint) throws SocketException {
+ this.epoint=epoint;
+ datagramSocket=new DatagramSocket(epoint);
+ ThreadTool.makeVDaemonThreadIfSupport("Datagram Distribute Thread", this).start();
}
-
- protected SubDatagramSocket(DatagramSocketImpl impl) {
- super(impl);
- }
-
- 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);
+
+ public DatagramSocket getDatagramSocket() {
+ return datagramSocket;
}
@Override
- public void connect(InetAddress address, int port) {
- super.connect(address, port);
- clients.put(new InetSocketAddress(address, port),this);
+ public void run() {
+ try {
+ 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 connect(SocketAddress addr) throws SocketException {
- super.connect(addr);
- clients.put(addr,this);
+ public void removeClient(SubDatagramSocket subDatagramSocket) {
+ clients.remove(subDatagramSocket.getRemoteSocketAddress());
+ }
+
+ }
+ 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 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
public void receive(DatagramPacket p) throws IOException {
- if(dp!=null) {
- p.setLength(dp.getLength());
- System.arraycopy(dp.getData(), dp.getOffset(), p.getData(), p.getOffset(), dp.getLength());
- dp=null;
- }else {
- super.receive(p);
- }
+ DatagramPacket dp=null;
+ long start=System.nanoTime();
+ while(true) {
+ if(closed) {
+ throw new SocketException("DatagramSocket closed");
+ }
+ 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
- public void disconnect() {
- super.disconnect();
- SocketAddress sa=getRemoteSocketAddress();
- if(sa!=null)
- clients.remove(sa);
+ public SocketAddress getRemoteSocketAddress() {
+ return remote;
}
- public void close() {
- super.close();
- SocketAddress sa=getRemoteSocketAddress();
- if(sa!=null)
- clients.remove(sa);
+ @Override
+ public InetAddress getInetAddress() {
+ return remote.getAddress();
}
+
+ @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();
+ }
}
diff --git a/src/org/kne/cloud/network/DatagramSocketListener.java b/src/org/kne/cloud/network/DatagramSocketListener.java
index de9beda..7d3c361 100644
--- a/src/org/kne/cloud/network/DatagramSocketListener.java
+++ b/src/org/kne/cloud/network/DatagramSocketListener.java
@@ -51,7 +51,7 @@ public class DatagramSocketListener implements Closeable,AutoCloseable{
if(serverSocket==null)
serverSocket=multipurposeSocketAddress.listenDatagramServerSocket();
//new Thread(r).start();
- ThreadTool.makeVThreadIfSupport("端口监听线程",r).start();
+ ThreadTool.makePThreadIfSupport("端口监听线程",r).start();
}
public void close() {
flag=false;
diff --git a/src/org/kne/cloud/network/DefaultMinecraftSocketBridgeFactory.java b/src/org/kne/cloud/network/DefaultMinecraftSocketBridgeFactory.java
new file mode 100644
index 0000000..0d5fdc3
--- /dev/null
+++ b/src/org/kne/cloud/network/DefaultMinecraftSocketBridgeFactory.java
@@ -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;
+
+ }
+
+}
diff --git a/src/org/kne/cloud/network/DefaultServerSocketChannelFactory.java b/src/org/kne/cloud/network/DefaultServerSocketChannelFactory.java
new file mode 100644
index 0000000..db3d3d3
--- /dev/null
+++ b/src/org/kne/cloud/network/DefaultServerSocketChannelFactory.java
@@ -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;
+ }
+
+}
diff --git a/src/org/kne/cloud/network/DefaultSocketBridgeFactory.java b/src/org/kne/cloud/network/DefaultSocketBridgeFactory.java
new file mode 100644
index 0000000..b4a40c0
--- /dev/null
+++ b/src/org/kne/cloud/network/DefaultSocketBridgeFactory.java
@@ -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);
+ }
+
+
+
+}
diff --git a/src/org/kne/cloud/network/DefaultSocketChannelBridgeFactory.java b/src/org/kne/cloud/network/DefaultSocketChannelBridgeFactory.java
new file mode 100644
index 0000000..b4f265b
--- /dev/null
+++ b/src/org/kne/cloud/network/DefaultSocketChannelBridgeFactory.java
@@ -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);
+ }
+
+
+
+}
diff --git a/src/org/kne/cloud/network/DefaultSocketChannelFactory.java b/src/org/kne/cloud/network/DefaultSocketChannelFactory.java
new file mode 100644
index 0000000..256aad8
--- /dev/null
+++ b/src/org/kne/cloud/network/DefaultSocketChannelFactory.java
@@ -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;
+ }
+
+}
diff --git a/src/org/kne/cloud/network/KLALBProxyConfigJsonExecuter.java b/src/org/kne/cloud/network/KLALBProxyConfigJsonExecuter.java
deleted file mode 100644
index ad1a2e0..0000000
--- a/src/org/kne/cloud/network/KLALBProxyConfigJsonExecuter.java
+++ /dev/null
@@ -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 proxys=new HashSet<>();
- private KLALBController klalbController;
- public Set 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());
- }
- }
-}
diff --git a/src/org/kne/cloud/network/MultipurposeSocketAddress.java b/src/org/kne/cloud/network/MultipurposeSocketAddress.java
index e3c3f17..f5018a5 100644
--- a/src/org/kne/cloud/network/MultipurposeSocketAddress.java
+++ b/src/org/kne/cloud/network/MultipurposeSocketAddress.java
@@ -10,8 +10,9 @@ import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
import java.util.*;
-import java.util.Objects;
import javax.net.ServerSocketFactory;
import javax.net.SocketFactory;
@@ -20,11 +21,11 @@ public class MultipurposeSocketAddress implements Serializable{
/**
*
*/
- private static Map socketTypeRegister=new HashMap<>();
+ private static final Map socketTypeRegister=new HashMap<>();
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()));
}
@@ -127,6 +128,11 @@ public class MultipurposeSocketAddress implements Serializable{
}
return sb.toString();
}
+
+
+
+
+
public Socket connectSocket(InetAddress bindip,int bindport,int timeout) throws UnknownHostException, IOException {
SocketFactory sf=socketTypeRegister.get(type).getSocketFactory();
if(sf==null) {
@@ -166,6 +172,69 @@ public class MultipurposeSocketAddress implements Serializable{
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 {
ServerSocketFactory srf=socketTypeRegister.get(type).getServerSocketFactory();
if(srf==null) {
@@ -182,6 +251,26 @@ public class MultipurposeSocketAddress implements Serializable{
ServerSocket sk=srf.createServerSocket(port, backlog, InetAddress.getByName(host));
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() {
return checkIsStream(type);
}
@@ -223,4 +312,20 @@ public class MultipurposeSocketAddress implements Serializable{
DatagramServerSocket sk=srf.createDatagramServerSocket(port, backlog, InetAddress.getByName(host));
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;
+ }
+ }
}
diff --git a/src/org/kne/cloud/network/PacketRebuilder.java b/src/org/kne/cloud/network/PacketRebuilder.java
new file mode 100644
index 0000000..88d7b6d
--- /dev/null
+++ b/src/org/kne/cloud/network/PacketRebuilder.java
@@ -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 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> iterator = recvc.entrySet().iterator(); iterator.hasNext();) {
+ Entry type = (Entry) 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();
+ }
+
+
+
+}
diff --git a/src/org/kne/cloud/network/PacketSpliter.java b/src/org/kne/cloud/network/PacketSpliter.java
new file mode 100644
index 0000000..7ca7f6f
--- /dev/null
+++ b/src/org/kne/cloud/network/PacketSpliter.java
@@ -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;
+ }
+
+}
diff --git a/src/org/kne/cloud/network/ServerSocketChannelFactory.java b/src/org/kne/cloud/network/ServerSocketChannelFactory.java
new file mode 100644
index 0000000..60c4853
--- /dev/null
+++ b/src/org/kne/cloud/network/ServerSocketChannelFactory.java
@@ -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 ;
+}
diff --git a/src/org/kne/cloud/network/SocketBridge.java b/src/org/kne/cloud/network/SocketBridge.java
index 27c0469..52d8ee9 100644
--- a/src/org/kne/cloud/network/SocketBridge.java
+++ b/src/org/kne/cloud/network/SocketBridge.java
@@ -4,6 +4,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.net.*;
+import org.kne.cloud.network.klalb.KLALBVirtualSocket;
import org.kne.io.Task;
public class SocketBridge extends Task{
protected Socket a;
@@ -29,11 +30,17 @@ public class SocketBridge extends Task{
@Override
protected void runTask() {
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");
bridgeBA.runAtNewThread("SocketBridge B->A thread");
bridgeAB.waitfortask();
bridgeBA.waitfortask();
- } catch (Exception e) {
+
+ }} catch (Exception e) {
e.printStackTrace();
}finally {
//new Exception().printStackTrace();
diff --git a/src/org/kne/cloud/network/SocketBridgeFactory.java b/src/org/kne/cloud/network/SocketBridgeFactory.java
new file mode 100644
index 0000000..70f97b6
--- /dev/null
+++ b/src/org/kne/cloud/network/SocketBridgeFactory.java
@@ -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;
+}
diff --git a/src/org/kne/cloud/network/SocketChannelBridge.java b/src/org/kne/cloud/network/SocketChannelBridge.java
new file mode 100644
index 0000000..5a35223
--- /dev/null
+++ b/src/org/kne/cloud/network/SocketChannelBridge.java
@@ -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();
+ }*/
+
+}
diff --git a/src/org/kne/cloud/network/SocketChannelBridgeFactory.java b/src/org/kne/cloud/network/SocketChannelBridgeFactory.java
new file mode 100644
index 0000000..8fffa6b
--- /dev/null
+++ b/src/org/kne/cloud/network/SocketChannelBridgeFactory.java
@@ -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;
+}
diff --git a/src/org/kne/cloud/network/SocketChannelFactory.java b/src/org/kne/cloud/network/SocketChannelFactory.java
new file mode 100644
index 0000000..27fb9a0
--- /dev/null
+++ b/src/org/kne/cloud/network/SocketChannelFactory.java
@@ -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 ;
+}
diff --git a/src/org/kne/cloud/network/SocketChannelListener.java b/src/org/kne/cloud/network/SocketChannelListener.java
new file mode 100644
index 0000000..abfdc76
--- /dev/null
+++ b/src/org/kne/cloud/network/SocketChannelListener.java
@@ -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 Consumercon;
+ 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 getCon() {
+ return con;
+ }
+
+ public void setCon(Consumer con) {
+ this.con = con;
+ }
+
+}
diff --git a/src/org/kne/cloud/network/SocketListener.java b/src/org/kne/cloud/network/SocketListener.java
index b222819..be7298d 100644
--- a/src/org/kne/cloud/network/SocketListener.java
+++ b/src/org/kne/cloud/network/SocketListener.java
@@ -26,7 +26,7 @@ public class SocketListener implements Closeable,AutoCloseable{
while(flag){
try {
Socket soce=serverSocket.accept();
- ThreadTool.makeVThreadIfSupport("端口监听线程",()->{
+ ThreadTool.makePThreadIfSupport("端口监听线程",()->{
if(con!=null) {
try {
con.accept(soce);
diff --git a/src/org/kne/cloud/network/SocketToSocketProxy.java b/src/org/kne/cloud/network/SocketToSocketProxy.java
index 836020b..1aac538 100644
--- a/src/org/kne/cloud/network/SocketToSocketProxy.java
+++ b/src/org/kne/cloud/network/SocketToSocketProxy.java
@@ -5,13 +5,18 @@ import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
+import java.nio.channels.SocketChannel;
import java.util.Map;
public class SocketToSocketProxy extends Proxy {
private SocketListener sl;
+ private SocketChannelListener scl;
private DatagramSocketListener dsl;
private MultipurposeSocketAddress listen, cbind, defaultConnect;
private Map detectedConnect;
+ private SocketBridgeFactory defaultFactory;
+ private SocketChannelBridgeFactory defaultChannelFactory;
+ private Map detectedFactory;
public SocketToSocketProxy(MultipurposeSocketAddress listen, MultipurposeSocketAddress connect) throws IOException {
this(listen, new MultipurposeSocketAddress(new InetSocketAddress(0)), connect);
@@ -24,10 +29,28 @@ public class SocketToSocketProxy extends Proxy {
public SocketToSocketProxy(MultipurposeSocketAddress listen, MultipurposeSocketAddress cbind,
MultipurposeSocketAddress defaultConnect, Map detectedConnect)
throws IOException {
+ this(listen,cbind,defaultConnect,detectedConnect,new DefaultSocketBridgeFactory(),null);
+ }
+
+ public SocketToSocketProxy(MultipurposeSocketAddress listen, MultipurposeSocketAddress cbind,
+ MultipurposeSocketAddress defaultConnect, Map detectedConnect,SocketBridgeFactory defaultFactory,Map detectedFactory)
+ throws IOException {
+ this(listen, cbind, defaultConnect, detectedConnect, defaultFactory, detectedFactory, new DefaultSocketChannelBridgeFactory());
+ }
+
+ public SocketToSocketProxy(MultipurposeSocketAddress listen, MultipurposeSocketAddress cbind,
+ MultipurposeSocketAddress defaultConnect, Map detectedConnect,SocketBridgeFactory defaultFactory,Map detectedFactory,SocketChannelBridgeFactory defaultChannelFactory)
+ throws IOException {
this.listen = listen;
this.cbind = cbind;
this.defaultConnect = defaultConnect;
this.detectedConnect = detectedConnect;
+
+ this.defaultFactory=defaultFactory;
+ this.detectedFactory=detectedFactory;
+
+ this.defaultChannelFactory=defaultChannelFactory;
+
open();
}
@@ -38,31 +61,67 @@ public class SocketToSocketProxy extends Proxy {
private void open() throws IOException {
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);
+ }
} else {
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) -> {
Socket sk = null;
try {
if (sox instanceof ProtocolDetectorSocket) {
ProtocolStack ps = ((ProtocolDetectorSocket) sox).getProtocolStack();
if (!ps.isEmpty()) {
- MultipurposeSocketAddress pmsa = detectedConnect.get(ps.pop().getName());
+ String pname=ps.pop().getName();
+ MultipurposeSocketAddress pmsa = detectedConnect.get(pname);
if(pmsa!=null) {
sk = pmsa.connectSocket(InetAddress.getByName(cbind.getHost()), cbind.getPort());
}else {
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 {
sk = defaultConnect.connectSocket(InetAddress.getByName(cbind.getHost()), cbind.getPort());
+ runBridge(defaultFactory,sox,sk);
}
} else {
sk = defaultConnect.connectSocket(InetAddress.getByName(cbind.getHost()), cbind.getPort());
+ runBridge(defaultFactory,sox,sk);
}
- runBridge(sox,sk);
} catch (IOException e) {
e.printStackTrace();
} finally {
@@ -79,6 +138,7 @@ public class SocketToSocketProxy extends Proxy {
}
}
});
+ }
} else {
dsl = new DatagramSocketListener(listen);
dsl.setCon((dox) -> {
@@ -87,8 +147,13 @@ public class SocketToSocketProxy extends Proxy {
}
}
- protected void runBridge(Socket sk, Socket sox) throws IOException {
- SocketBridge sb = new SocketBridge(sk, sox);
+ protected void runBridge(SocketBridgeFactory sbf,Socket sk, Socket sox) throws IOException {
+ 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();
}
@@ -103,6 +168,24 @@ public class SocketToSocketProxy extends Proxy {
public MultipurposeSocketAddress getDefaultConnect() {
return defaultConnect;
}
+
+ public Map getDetectedConnect() {
+ return detectedConnect;
+ }
+
+ public SocketBridgeFactory getDefaultFactory() {
+ return defaultFactory;
+ }
+
+ public Map getDetectedFactory() {
+ return detectedFactory;
+ }
+
+
+
+ public SocketChannelBridgeFactory getDefaultChannelFactory() {
+ return defaultChannelFactory;
+ }
@Override
public void close() throws IOException {
@@ -110,12 +193,20 @@ public class SocketToSocketProxy extends Proxy {
dsl.close();
if (sl != null)
sl.close();
+ if(scl!=null)
+ scl.close();
}
public InetAddress getListenAddress() {
if (sl != null) {
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();
}
}
@@ -123,6 +214,12 @@ public class SocketToSocketProxy extends Proxy {
public int getListenPort() {
if (sl != null) {
return sl.getServerSocket().getLocalPort();
+ } else if(scl!=null){
+ try {
+ return ((InetSocketAddress)scl.getServerSocketChannel().getLocalAddress()).getPort();
+ } catch (IOException e) {
+ return -1;
+ }
} else {
return dsl.getDatagramServerSocket().getLocalPort();
}
diff --git a/src/org/kne/cloud/network/SocketType.java b/src/org/kne/cloud/network/SocketType.java
index 2cec2ce..d12d18f 100644
--- a/src/org/kne/cloud/network/SocketType.java
+++ b/src/org/kne/cloud/network/SocketType.java
@@ -8,11 +8,15 @@ import javax.net.SocketFactory;
public class SocketType {
private SocketFactory socketFactory;
private ServerSocketFactory serverSocketFactory;
+
+ private SocketChannelFactory socketChannelFactory;
+ private ServerSocketChannelFactory serverSocketChannelFactory;
+
private DatagramSocketFactory datagramSocketFactory;
private DatagramServerSocketFactory datagramServerSocketFactory;
private boolean stream;
- public SocketFactory getSocketFactory() {
+ public SocketFactory Channel() {
return socketFactory;
}
@@ -23,11 +27,33 @@ public class SocketType {
public DatagramSocketFactory getDatagramSocketFactory() {
return datagramSocketFactory;
}
+
+ public SocketChannelFactory getSocketChannelFactory() {
+ return socketChannelFactory;
+ }
+
+ public ServerSocketChannelFactory getServerSocketChannelFactory() {
+ return serverSocketChannelFactory;
+ }
+
+ public SocketFactory getSocketFactory() {
+ return socketFactory;
+ }
public DatagramServerSocketFactory getDatagramServerSocketFactory() {
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) {
super();
diff --git a/src/org/kne/cloud/network/SpeedLimiter.java b/src/org/kne/cloud/network/SpeedLimiter.java
new file mode 100644
index 0000000..01b2dc2
--- /dev/null
+++ b/src/org/kne/cloud/network/SpeedLimiter.java
@@ -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);
+ }
+ }
+
+}
diff --git a/src/org/kne/cloud/network/StreamBridge.java b/src/org/kne/cloud/network/StreamBridge.java
index ea5d97d..a2da102 100644
--- a/src/org/kne/cloud/network/StreamBridge.java
+++ b/src/org/kne/cloud/network/StreamBridge.java
@@ -30,15 +30,17 @@ public class StreamBridge extends Task{
// fos.write(b, 0, v);
out.write(b,0,v);
out.flush();
- if(delay>0)
+ if(delay>0) {
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
e.printStackTrace();
}
+ }else {
+ Thread.yield();
+ }
}
} catch (IOException e) {
- // TODO 自动生成的 catch 块
e.printStackTrace();
}finally {
/*if(fos!=null)
@@ -51,14 +53,12 @@ public class StreamBridge extends Task{
if(in!=null)
in.close();
} catch (IOException e) {
- // TODO 自动生成的 catch 块
e.printStackTrace();
}
try {
if(in!=null)
out.close();
} catch (IOException e) {
- // TODO 自动生成的 catch 块
e.printStackTrace();
}
}
diff --git a/src/org/kne/cloud/network/StreamChannelBridge.java b/src/org/kne/cloud/network/StreamChannelBridge.java
new file mode 100644
index 0000000..05f27f3
--- /dev/null
+++ b/src/org/kne/cloud/network/StreamChannelBridge.java
@@ -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();
+ }
+
+}
diff --git a/src/org/kne/cloud/network/TimeoutTimer.java b/src/org/kne/cloud/network/TimeoutTimer.java
new file mode 100644
index 0000000..cd10c83
--- /dev/null
+++ b/src/org/kne/cloud/network/TimeoutTimer.java
@@ -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;
+ }
+}
diff --git a/src/org/kne/cloud/network/VirtualServerSocket.java b/src/org/kne/cloud/network/VirtualServerSocket.java
index 80137ed..b0d9300 100644
--- a/src/org/kne/cloud/network/VirtualServerSocket.java
+++ b/src/org/kne/cloud/network/VirtualServerSocket.java
@@ -48,7 +48,7 @@ public abstract class VirtualServerSocket extends ServerSocket {
}*/
}
- public VirtualSocketImpl getVirtualImpl() {
+ protected VirtualSocketImpl getVirtualImpl() {
return virtualImpl;
}
diff --git a/src/org/kne/cloud/network/VirtualSocket.java b/src/org/kne/cloud/network/VirtualSocket.java
index 1665fdc..9cb46c6 100644
--- a/src/org/kne/cloud/network/VirtualSocket.java
+++ b/src/org/kne/cloud/network/VirtualSocket.java
@@ -15,7 +15,7 @@ public abstract class VirtualSocket extends Socket {
private VirtualSocketImpl virtualImpl;
- public VirtualSocketImpl getVirtualImpl() {
+ protected VirtualSocketImpl getVirtualImpl() {
return virtualImpl;
}
diff --git a/src/org/kne/cloud/network/frpc/FrpcIni.java b/src/org/kne/cloud/network/frpc/FrpcIni.java
index d47d0c4..ff9f66d 100644
--- a/src/org/kne/cloud/network/frpc/FrpcIni.java
+++ b/src/org/kne/cloud/network/frpc/FrpcIni.java
@@ -19,31 +19,26 @@ public class FrpcIni extends Ini {
public FrpcIni(File input) throws IOException, InvalidFileFormatException {
super(input);
- // TODO 自动生成的构造函数存根
}
public FrpcIni(InputStream input) throws IOException, InvalidFileFormatException {
super(input);
- // TODO 自动生成的构造函数存根
}
public FrpcIni(Reader input) throws IOException, InvalidFileFormatException {
super(input);
- // TODO 自动生成的构造函数存根
}
public FrpcIni(URL input) throws IOException, InvalidFileFormatException {
super(input);
- // TODO 自动生成的构造函数存根
}
- public FrpcIni(String str) throws InvalidFileFormatException {
- this();
- loadFromString(str);
+ public FrpcIni(String str) throws IOException ,InvalidFileFormatException{
+ super(new StringReader(str));
}
public void setServerAddr(String addr) {
- add("common", "server_addr", addr);
+ put("common", "server_addr", addr);
}
public String getServerAddr() {
@@ -51,7 +46,7 @@ public class FrpcIni extends Ini {
}
public void setToken(String addr) {
- add("common", "token", addr);
+ put("common", "token", addr);
}
public String getToken() {
@@ -59,7 +54,7 @@ public class FrpcIni extends Ini {
}
public void setProtocol(String protocol) {
- add("common", "protocol", protocol);
+ put("common", "protocol", protocol);
}
public String getProtocol() {
@@ -67,7 +62,7 @@ public class FrpcIni extends Ini {
}
public void setServerPort(int port) {
- add("common", "server_port", port);
+ put("common", "server_port", port);
}
public int getServerPort() {
@@ -75,14 +70,14 @@ public class FrpcIni extends Ini {
}
public void setDnsServer(String dns) {
- add("common", "dns_server", dns);
+ put("common", "dns_server", dns);
}
public String getDnsServer() {
return get("common", "dns_server");
}
public void setConnectServerLocalIp(String connectserverlocalip) {
- add("common", "connect_server_local_ip", connectserverlocalip);
+ put("common", "connect_server_local_ip", connectserverlocalip);
}
public String getConnectServerLocalIp() {
@@ -90,7 +85,7 @@ public class FrpcIni extends Ini {
}
public void setUser(String user) {
- add("common", "user", user);
+ put("common", "user", user);
}
public String getUser() {
@@ -98,7 +93,7 @@ public class FrpcIni extends Ini {
}
public void setTcpMux(boolean tcpmux) {
- add("common", "tcp_mux", tcpmux);
+ put("common", "tcp_mux", tcpmux);
}
public boolean getTcpMux() {
@@ -106,7 +101,7 @@ public class FrpcIni extends Ini {
}
public void setTlsEnable(boolean tlsenable) {
- add("common", "tls_enable", tlsenable);
+ put("common", "tls_enable", tlsenable);
}
public boolean getTlsEnable() {
@@ -125,63 +120,63 @@ public class FrpcIni extends Ini {
public void setType(String tunnel,String type) {
- add(tunnel, "type", type);
+ put(tunnel, "type", type);
}
public String getType(String tunnel) {
return get(tunnel, "type");
}
public void setLocalIP (String tunnel,String localip) {
- add(tunnel, "local_ip", localip);
+ put(tunnel, "local_ip", localip);
}
public String getLocalIP(String tunnel) {
return get(tunnel, "local_ip");
}
public void setLocalPort (String tunnel,int localport) {
- add(tunnel, "local_port", localport);
+ put(tunnel, "local_port", localport);
}
public int getLocalPort(String tunnel) {
return get(tunnel, "local_port",int.class);
}
public void setRemotePort (String tunnel,int remoteport) {
- add(tunnel, "remote_port", remoteport);
+ put(tunnel, "remote_port", remoteport);
}
public int getRemotePort(String tunnel) {
return get(tunnel, "remote_port",int.class);
}
public void setUseEncryption (String tunnel,boolean useencryption) {
- add(tunnel, "use_encryption", useencryption);
+ put(tunnel, "use_encryption", useencryption);
}
public boolean getUseEncryption(String tunnel) {
return get(tunnel, "use_encryption",boolean.class);
}
public void setUseCompression (String tunnel,boolean usecompression) {
- add(tunnel, "use_compression", usecompression);
+ put(tunnel, "use_compression", usecompression);
}
public boolean getUseCompression(String tunnel) {
return get(tunnel, "use_compression",boolean.class);
}
public void setSk(String tunnel,String sk) {
- add(tunnel, "sk", sk);
+ put(tunnel, "sk", sk);
}
public String getSk(String tunnel) {
return get(tunnel, "sk");
}
public void setRole(String tunnel,String sk) {
- add(tunnel, "role", sk);
+ put(tunnel, "role", sk);
}
public String getRole(String tunnel) {
return get(tunnel, "role");
}
public void setServerName(String tunnel,String servername) {
- add(tunnel, "server_name", servername);
+ put(tunnel, "server_name", servername);
}
public String getServerName(String tunnel) {
@@ -189,21 +184,21 @@ public class FrpcIni extends Ini {
}
public void setBindAddr(String tunnel,String bindaddr) {
- add(tunnel, "bind_addr", bindaddr);
+ put(tunnel, "bind_addr", bindaddr);
}
public String getBindAddr(String tunnel) {
return get(tunnel, "bind_addr");
}
public void setBindPort (String tunnel,int bindport) {
- add(tunnel, "bind_port", bindport);
+ put(tunnel, "bind_port", bindport);
}
public int getBindPort(String tunnel) {
return get(tunnel, "bind_port",int.class);
}
public void setKeepTunnelOpen (String tunnel,boolean keeptunnelopen) {
- add(tunnel, "keep_tunnel_open", keeptunnelopen);
+ put(tunnel, "keep_tunnel_open", keeptunnelopen);
}
public boolean getKeepTunnelOpen(String tunnel) {
@@ -215,6 +210,7 @@ public class FrpcIni extends Ini {
StringWriter sw = new StringWriter();
try {
store(sw);
+ //System.out.println(sw);
} catch (IOException e) {
e.printStackTrace();
}
diff --git a/src/org/kne/cloud/network/frpc/FrpcProcess.java b/src/org/kne/cloud/network/frpc/FrpcProcess.java
index f109bc5..2f9afac 100644
--- a/src/org/kne/cloud/network/frpc/FrpcProcess.java
+++ b/src/org/kne/cloud/network/frpc/FrpcProcess.java
@@ -38,6 +38,8 @@ public class FrpcProcess extends Process{
private File base;
private File exe;
private Process theProcess;
+
+ private File config_file;
public FrpcProcess(String ini) throws IOException {
this(defaultBase,ini);
@@ -50,11 +52,14 @@ public class FrpcProcess extends Process{
}else {
exe=new File(base,"frpc_linux_amd64");
}
- File f=new File(base,"frpc_conf.ini");
- f.createNewFile();
+ AtomicReferencearex=new AtomicReference();
+ synchronized (getClass()) {
+ config_file = new File(base,"frpc_conf_"+UUID.randomUUID()+".ini");
+ config_file.createNewFile();
+ config_file.deleteOnExit();
PrintWriter ps=null;
try {
- ps=new PrintWriter(f);
+ ps=new PrintWriter(config_file);
ps.println(ini);
}finally {
if(ps!=null)
@@ -63,12 +68,23 @@ public class FrpcProcess extends Process{
Listlstc=new ArrayList<>();
lstc.add(exe.getAbsolutePath());
lstc.add("-c");
- lstc.add(f.getName());
+ lstc.add(config_file.getName());
ProcessBuilder psb=new ProcessBuilder(lstc);
psb.directory(base);
theProcess=psb.start();
- AtomicReferencearex=new AtomicReference();
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(()->{
BufferedReader br=new BufferedReader(new InputStreamReader(theProcess.getInputStream()));
@@ -78,6 +94,7 @@ public class FrpcProcess extends Process{
if(s==null) {
break;
}
+ cdl.countDown();
System.out.println (s);
if(s.contains("start proxy success")) {
t.interrupt();
@@ -93,6 +110,9 @@ public class FrpcProcess extends Process{
}else if(s.contains("already exists")&&s.contains("proxy")) {
arex.set(new BindException("proxy already exists"));
t.interrupt();
+ }else if(s.contains("已经存在, 请检查是否重复开启")&&s.contains("隧道")) {
+ arex.set(new BindException("proxy already exists"));
+ t.interrupt();
}
}
} catch (IOException e) {
@@ -106,6 +126,13 @@ public class FrpcProcess extends Process{
}
}).start();
+ try {
+ cdl.await(5000, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
try {
if(theProcess.waitFor(20000, TimeUnit.MILLISECONDS)) {
destroy();
@@ -115,23 +142,17 @@ public class FrpcProcess extends Process{
throw new SocketException("Frpc timed out");
}
} catch (InterruptedException e) {
+ //destroy();
+ Thread.interrupted();
if(arex.get()!=null) {
destroy();
arex.get().fillInStackTrace();
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() {
return base;
@@ -163,6 +184,9 @@ public class FrpcProcess extends Process{
if(hook!=null) {
Runtime.getRuntime().removeShutdownHook(hook);
}
+ if(config_file!=null) {
+ config_file.delete();
+ }
}
@Override
public boolean waitFor(long timeout, TimeUnit unit) throws InterruptedException {
diff --git a/src/org/kne/cloud/network/frpc/FrpcServerSocket.java b/src/org/kne/cloud/network/frpc/FrpcServerSocket.java
index 70dddae..91fccd7 100644
--- a/src/org/kne/cloud/network/frpc/FrpcServerSocket.java
+++ b/src/org/kne/cloud/network/frpc/FrpcServerSocket.java
@@ -10,6 +10,7 @@ import java.net.SocketImpl;
import java.net.UnknownHostException;
import java.util.Iterator;
import java.util.Map.Entry;
+import java.util.Set;
import org.ini4j.Profile.Section;
import org.kne.cloud.network.MultipurposeSocketAddress;
@@ -85,7 +86,7 @@ public class FrpcServerSocket extends ServerSocket {
public void bind(SocketAddress endpoint, int backlog) throws IOException {
if(frpcini!=null) {
if(tunnel==null) {
- var e=frpcini.keySet();
+ Set e=frpcini.keySet();
for (Iterator iterator = e.iterator(); iterator.hasNext();) {
String key = iterator.next();
if(!key.equals("common")) {
diff --git a/src/org/kne/cloud/network/frpc/FrpcToml.java b/src/org/kne/cloud/network/frpc/FrpcToml.java
new file mode 100644
index 0000000..aa6b2b7
--- /dev/null
+++ b/src/org/kne/cloud/network/frpc/FrpcToml.java
@@ -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(""));
+ }
+}
diff --git a/src/org/kne/cloud/network/klalb/ACKTPacket.java b/src/org/kne/cloud/network/klalb/ACKTPacket.java
index d2d1ad3..50e2a18 100644
--- a/src/org/kne/cloud/network/klalb/ACKTPacket.java
+++ b/src/org/kne/cloud/network/klalb/ACKTPacket.java
@@ -5,114 +5,57 @@ import java.io.DataInputStream;
import java.io.DataOutput;
import java.io.DataOutputStream;
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;
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) {
super(ACKT);
- this.sport=sport;
- this.dport=dport;
- this.number=number;
- this.avaliable=avaliable;
- this.sendcount=sendcount;
+ header.putInt(sport);
+ header.putInt(dport);
+ header.putLong(number);
+ header.put((byte) sendcount);
+ header.put((byte) (avaliable?1:0));
}
- public ACKTPacket() {
- super(ACKT);
+ public ACKTPacket(ByteBuffer bb) {
+ super(bb);
}
@Override
public String toString() {
- return "ACKT "+sport+"->"+dport+" "+number+"[] "+avaliable;
+ return "ACKT "+getSport()+"->"+getDport()+" "+getNumber()+"[] "+isAvaliable();
}
public int getSport() {
- return sport;
+ return header.getInt(1);
}
@Override
- public long getLength() {
- return super.getLength()+18;
+ public int getHeaderSize() {
+ return super.getHeaderSize()+18;
}
public int getDport() {
- return dport;
+ return header.getInt(5);
}
public long getNumber() {
- return number;
+ return header.getLong(9);
}
public boolean isAvaliable() {
- return avaliable;
+ return header.get(18)!=0;
}
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);
- }
-
}
\ No newline at end of file
diff --git a/src/org/kne/cloud/network/klalb/ADDLINESPacket.java b/src/org/kne/cloud/network/klalb/ADDLINESPacket.java
index d941d12..226e272 100644
--- a/src/org/kne/cloud/network/klalb/ADDLINESPacket.java
+++ b/src/org/kne/cloud/network/klalb/ADDLINESPacket.java
@@ -1,9 +1,17 @@
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.EOFException;
import java.io.IOException;
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 {
private String lines;
@@ -18,43 +26,49 @@ public class ADDLINESPacket extends KLALBPacket {
this.lines=lines;
}
- public ADDLINESPacket() {
- super(ADDLINES);
- }
- 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;
+
+ public ADDLINESPacket(ByteBuffer bb) {
+ super(bb);
}
+
+
@Override
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
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();
- }
}
diff --git a/src/org/kne/cloud/network/klalb/BWINFPacket.java b/src/org/kne/cloud/network/klalb/BWINFPacket.java
new file mode 100644
index 0000000..9124c27
--- /dev/null
+++ b/src/org/kne/cloud/network/klalb/BWINFPacket.java
@@ -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";
+ }
+
+}
diff --git a/src/org/kne/cloud/network/klalb/ByteArrayPool.java b/src/org/kne/cloud/network/klalb/ByteArrayPool.java
new file mode 100644
index 0000000..d507d55
--- /dev/null
+++ b/src/org/kne/cloud/network/klalb/ByteArrayPool.java
@@ -0,0 +1,35 @@
+package org.kne.cloud.network.klalb;
+
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+public class ByteArrayPool {
+ private ArrayBlockingQueuerec;
+ private int maxcount;
+ private int length;
+ public ByteArrayPool(int maxcount, int length) {
+ super();
+ this.maxcount = maxcount;
+ this.length = length;
+ rec=new ArrayBlockingQueue(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;
+ }
+
+}
diff --git a/src/org/kne/cloud/network/klalb/ByteArrayRecycle.java b/src/org/kne/cloud/network/klalb/ByteArrayRecycle.java
deleted file mode 100644
index 0516448..0000000
--- a/src/org/kne/cloud/network/klalb/ByteArrayRecycle.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package org.kne.cloud.network.klalb;
-
-import java.util.concurrent.ConcurrentLinkedQueue;
-
-public class ByteArrayRecycle {
- private ConcurrentLinkedQueuerec=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()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(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;
+ }
+
+}
diff --git a/src/org/kne/cloud/network/klalb/CONST.java b/src/org/kne/cloud/network/klalb/CONST.java
index 396ed3b..af90078 100644
--- a/src/org/kne/cloud/network/klalb/CONST.java
+++ b/src/org/kne/cloud/network/klalb/CONST.java
@@ -2,5 +2,5 @@ package org.kne.cloud.network.klalb;
public class CONST {
public static String klalb="KLALB";
- public static String klalbver="2.2";
+ public static String klalbver="2.3";
}
diff --git a/src/org/kne/cloud/network/klalb/DATATPacket.java b/src/org/kne/cloud/network/klalb/DATATPacket.java
index 091d044..9a28874 100644
--- a/src/org/kne/cloud/network/klalb/DATATPacket.java
+++ b/src/org/kne/cloud/network/klalb/DATATPacket.java
@@ -1,168 +1,140 @@
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.EOFException;
import java.io.IOException;
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.zip.CRC32;
import javax.sound.sampled.Port;
-public class DATATPacket extends KLALBPacket implements Comparable,PortPacket{
- public static final ByteArrayRecycle arrayRecycle=new ByteArrayRecycle(5000,65535);
- @Override
- public long getLength() {
- return super.getLength()+19+size;
- }
-
- private int sport,dport;
+public class DATATPacket extends KLALBPacket implements PortPacket{
+ /*private int sport,dport;
private long number;
private int size;
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();
- 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);
- this.sport=sport;
+ /*this.sport=sport;
this.dport=dport;
this.number=number;
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() {
- return sendcount;
+ return header.get(17);
}
public DATATPacket() {
super(DATAT);
}
+ public DATATPacket(ByteBuffer bb) {
+ super(bb);
+ }
+
public int getSport() {
- return sport;
+ return header.getInt(1);
}
public int getDport() {
- return dport;
+ return header.getInt(5);
}
public long getNumber() {
- return number;
+ return header.getLong(9);
}
- public byte[] getData() {
+ public ByteBuffer getDataBuffer() {
return data;
}
@Override
public String toString() {
- return "DATAT "+sport+"->"+dport+" "+number+"["+size+"]";
- }
- 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!");
- }*/
+ return "DATAT "+getSport()+"->"+getDport()+" "+getNumber()+"["+getSize()+"]";
}
+
@Override
public int hashCode() {
- return Objects.hash(number);
+ return (int) getNumber();
}
@Override
public boolean equals(Object obj) {
- if (this == obj)
- return true;
if (obj == null)
return false;
- if (getClass() != obj.getClass())
- return false;
+ try {
DATATPacket other = (DATATPacket) obj;
- return number == other.number;
+ return getNumber() == other.getNumber();
+ }catch(ClassCastException e) {
+ return false;
+ }
}
public int getSize() {
- return size;
+ return data.limit();
}
@Override
- public int compareTo(DATATPacket o) {
- if(number>o.number) {
- return 1;
- }else if(number>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;
+ }
}
diff --git a/src/org/kne/cloud/network/klalb/KLALBController.java b/src/org/kne/cloud/network/klalb/KLALBController.java
index 1843d71..dd9226a 100644
--- a/src/org/kne/cloud/network/klalb/KLALBController.java
+++ b/src/org/kne/cloud/network/klalb/KLALBController.java
@@ -3,6 +3,7 @@ package org.kne.cloud.network.klalb;
import java.io.IOException;
import java.net.BindException;
import java.net.ConnectException;
+import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
@@ -12,10 +13,13 @@ import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.SocketTimeoutException;
+import java.net.UnknownHostException;
+import java.time.Clock;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -23,10 +27,14 @@ import java.util.Map.Entry;
import java.util.Scanner;
import java.util.Set;
import java.util.Timer;
+import java.util.TimerTask;
import java.util.UUID;
import java.util.Vector;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
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.ReentrantReadWriteLock;
import java.util.function.BiConsumer;
@@ -37,11 +45,14 @@ import javax.management.openmbean.ArrayType;
import javax.net.ServerSocketFactory;
import javax.net.SocketFactory;
+import org.kne.cloud.clock.AdjustedNanoClock;
import org.kne.cloud.network.MultipurposeSocketAddress;
import org.kne.cloud.network.NetworkService;
import org.kne.cloud.network.Proxy;
import org.kne.cloud.network.SocketType;
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 javassist.ClassPool;
@@ -52,11 +63,147 @@ import javassist.bytecode.CodeAttribute;
import javassist.bytecode.CodeIterator;
public class KLALBController {
+
+ private SpeedAndTrafficMonitorDataImpl linkMonitor=new SpeedAndTrafficMonitorDataImpl();
+
+ private SpeedAndTrafficMonitorDataImpl datatMonitor=new SpeedAndTrafficMonitorDataImpl();
+
+ private ListselflineTable=new ArrayList<>();
+ private Timer twk=new Timer("网卡检测扫描计时器", true);
+ {
+
+ twk.schedule(new TimerTask() {
+
+ @Override
+ public void run() {
+ try {
+ Enumerationeu= NetworkInterface.getNetworkInterfaces();
+ while (eu.hasMoreElements()) {
+ NetworkInterface networkInterface = (NetworkInterface) eu.nextElement();
+ if(networkInterface.isUp()) {
+ //System.out.println(networkInterface+" "+networkInterface.isUp());
+ Enumerationei= networkInterface.getInetAddresses();
+ while (ei.hasMoreElements()) {
+ InetAddress inetAddress = (InetAddress) ei.nextElement();
+
+ for (Iterator 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 {
+ Listlocaladdress=new ArrayList<>();
+ Enumerationeu= NetworkInterface.getNetworkInterfaces();
+ while (eu.hasMoreElements()) {
+ NetworkInterface networkInterface = (NetworkInterface) eu.nextElement();
+ if(networkInterface.isUp()) {
+ //System.out.println(networkInterface+" "+networkInterface.isUp());
+ Enumerationei= networkInterface.getInetAddresses();
+ while (ei.hasMoreElements()) {
+ InetAddress inetAddress = (InetAddress) ei.nextElement();
+ MultipurposeSocketAddress bind=new MultipurposeSocketAddress(inetAddress.getHostAddress(),0);
+ localaddress.add(bind);
+
+ }
+ }
+ }
+ Setst=new HashSet<>();
+ for (Iterator iterator = lines.iterator(); iterator.hasNext();) {
+ KLALBRemoteLine multipurposeSocketAddress = (KLALBRemoteLine) iterator.next();
+ if(multipurposeSocketAddress.getSocketAddress()!=null)
+ st.add(multipurposeSocketAddress.getSocketAddress());
+ }
+
+
+ for (Iterator iterator = st.iterator(); iterator.hasNext();) {
+ MultipurposeSocketAddress multipurposeSocketAddress = (MultipurposeSocketAddress) iterator
+ .next();
+ for (Iterator 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 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 ConcurrentHashMapclocks=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();
+
public class KLALBSocketType extends SocketType{
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;
}
- private Supplier selflineTableSupplier=()->{return null;};
+
+
+ //private Supplier selflineTableSupplier=()->{return null;};
- public Supplier getSelflineTableSupplier() {
+ /*public Supplier getSelflineTableSupplier() {
return selflineTableSupplier;
}
public void setSelflineTableSupplier(Supplier selflineTableSupplier) {
this.selflineTableSupplier = selflineTableSupplier;
+ }*/
+
+ public List getSelflineTable() {
+ return selflineTable;
}
+
private Inet6Address self;
public Inet6Address getSelf() {
return self;
}
- private List lines=new ArrayList<>();
+ private List lines=new CopyOnWriteArrayList<>();
//private ReadWriteLock lineslock=new ReentrantReadWriteLock();
public List getLines() {
@@ -95,12 +249,10 @@ public class KLALBController {
public void reconnectImmediately() {
- synchronized (lines) {
for (Iterator iterator = lines.iterator(); iterator.hasNext();) {
KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) iterator.next();
klalbRemoteLine.reconnectImmediately();
}
- }
}
private PacketReceiver prc=new PacketReceiver();
@@ -113,21 +265,26 @@ public class KLALBController {
PortPacket pt=(PortPacket) rec;
if(!streamPortBinder.distributePacketToConsumer(krs, pt)) {
if(!(pt instanceof RSTPacket))
- sendPacketToAddress(krs.getRemoteVaddr(), new RSTPacket(pt.getDport(), pt.getSport()),
- 0,2);
+ sendPacketToAddress(krs.getRemoteVaddr(), new RSTPacket(pt.getDport(), pt.getSport()),2);
}
}else {
switch (rec.getType()) {
case KLALBPacket.ADDLINES:
ADDLINESPacket lpt=(ADDLINESPacket) rec;
String s=lpt.getLines();
+ ThreadTool.makeVDaemonThreadIfSupport("线路添加任务", ()->{
Scanner scn=new Scanner(s);
while(scn.hasNext()) {
String sn=scn.nextLine();
MultipurposeSocketAddress msa= new MultipurposeSocketAddress(sn);
- addRemoteLines(msa);
+ try {
+ addRemoteLines(msa);
+ } catch (SocketTimeoutException e) {
+ } catch (SocketException e) {
+ }
}
+ }).start();
break;
default:
break;
@@ -142,7 +299,6 @@ public class KLALBController {
}
public void addRemoteLines(MultipurposeSocketAddress target) throws SocketTimeoutException, SocketException {
- synchronized (lines) {
try {
Enumerationeu= NetworkInterface.getNetworkInterfaces();
@@ -154,6 +310,15 @@ public class KLALBController {
while (ei.hasMoreElements()) {
InetAddress inetAddress = (InetAddress) ei.nextElement();
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)) {
//System.out.println(target+" "+bind);
addRemoteLine( new KLALBRemoteLine(target,bind));
@@ -164,21 +329,21 @@ public class KLALBController {
} catch (SocketException e) {
if(!checkContainsTarget(target))
addRemoteLine( new KLALBRemoteLine(target));
- throw e;
+ //throw e;
}
- }
+
}
public Inet6Address getRemoteVaddrBySocketAddress(MultipurposeSocketAddress target) throws SocketTimeoutException {
KLALBRemoteLine kr=null;
- synchronized(lines) {
- for (Iterator iterator = lines.iterator(); iterator.hasNext();) {
+ for (Iterator iterator = lines.iterator(); iterator.hasNext();) {
KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) iterator.next();
- if(target.equals(klalbRemoteLine.getSocketAddress())) {
+ if(target.equals(klalbRemoteLine.getSocketAddress())&&klalbRemoteLine.getBindAddress()==null) {
kr=klalbRemoteLine;
+ break;
}
}
- }
+
if(kr==null) {
kr=new KLALBRemoteLine(target);
addRemoteLine(kr);
@@ -213,19 +378,28 @@ public class KLALBController {
return b;
}
- public void addRemoteLine(KLALBRemoteLine krs) throws SocketTimeoutException {
+ public void addRemoteLine(KLALBRemoteLine krs) {
krs.setPacketReceiver(prc);
+ krs.setKlalbController(this);
krs.setLocalVaddrSupplier(()->{return self;});
krs.startIO();
- String selflineTable=selflineTableSupplier.get();
- if(selflineTable!=null)
- krs.sendPacket(new ADDLINESPacket(selflineTable), 0);
- synchronized (lines) {
+ String selflineTable=generateSelfLineTable();
+ if(selflineTable!=null&&!selflineTable.equals(""))
+ krs.sendPacket(new ADDLINESPacket(selflineTable));
lines.add(krs);
- }
}
+ private String generateSelfLineTable() {
+ StringBuilder sbd=new StringBuilder();
+ for (Iterator iterator = selflineTable.iterator(); iterator.hasNext();) {
+ MultipurposeSocketAddress klalbRemoteLine = (MultipurposeSocketAddress) iterator.next();
+ sbd.append(klalbRemoteLine.toString());
+ sbd.append('\n');
+ }
+ return sbd.toString();
+ }
+
public KLALBController(Inet6Address self) {
this.self = self;
}
@@ -238,16 +412,51 @@ public class KLALBController {
return new KLALBVirtualSocketImpl(this);
}
+
+
- protected void sendPacketToAddress(Inet6Address addr, KLALBPacket syntPacket, int priority)
+ protected void sendPacketToAddress(Inet6Address addr, KLALBPacket packet)
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> lines2 =new ConcurrentHashMap<>();
+ for (Iterator 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 {
+ ArrayListal1=new ArrayList<>();
+ al1.add(klalbRemoteLine);
+ lines2.put(klalbRemoteLine.getRemoteVaddr(), al1);
+ }
+ }
+ }
+ }
+ for (Iterator>> iterator = lines2.entrySet().iterator(); iterator.hasNext();) {
+ Entry> klalbRemoteLine = (Entry>) 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 {
List l=new ArrayList();
- synchronized (lines) {
for (int i = 0; i < lines.size(); i++) {
KLALBRemoteLine klalbRemoteLine = lines.get(i);
if(klalbRemoteLine.isClosed()) {
@@ -255,103 +464,120 @@ public class KLALBController {
i--;
continue;
}
- if(addr.equals(klalbRemoteLine.getRemoteVaddr())&&klalbRemoteLine.getMonitor().getState()==Monitor.ONLINE) {
+ if(addr.equals(klalbRemoteLine.getRemoteVaddr())&&klalbRemoteLine.getMonitor().getState()==MonitorData.ONLINE) {
l.add(klalbRemoteLine);
}
}
- }
+
if(l.isEmpty()) {
lines2.remove(addr);
}else {
+ l.forEach((r)->{
+ r.runPredict();
+ });
+ Collections.sort(l);
lines2.put(addr, l);
}
}
private Map> 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 {
- /*if(packet instanceof RSTPacket) {
- new Exception("-RST-").printStackTrace();
- }*/
+ if(packet==null)
+ throw new NullPointerException("packet is null!");
//TimeDebugger tdb=new TimeDebugger();
- //tdb.putTime("start");
+
+ //tdb.putTime("start");
+ packet.genseq();
+ loop:while(true) {
+ if(packet.isDisposed())
+ return;
List lines2x;
- //loop:while(true) {
- long cur=System.nanoTime();
- if(cur-itm>10000000L) {
- itm=cur;
- lines2.clear();
- }
+
lines2x=lines2.get(addr);
- if (lines2x == null || lines2x.isEmpty()) {
- updateLines2(addr);
- lines2x=lines2.get(addr);
- }
+
if (lines2x == null || lines2x.isEmpty()) {
throw new NoRouteToHostException("address unreachable: " + addr);
}
- //tdb.putTime("selectLines");
- /* for (Iterator 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 l2 = (List) ((ArrayList) lines2x).clone();
- l2.removeAll(packet.getSendRecord());
- if(l2.isEmpty()) {
- l2 = (List) ((ArrayList) lines2x).clone();
- }
-
- //tdb.putTime("findAvaliable");
- int count0 = Math.min(count, l2.size());
- l2.forEach((r)->{
- r.runPredict(packet,priority);
- });
- //Collections.shuffle(l2);
- Collections.sort(l2);
- //tdb.putTime("makeDecision");
- //System.out.println(l2);
- for (int i = 0; i < l2.size(); i++) {
- KLALBRemoteLine krst =l2.get(i);
- krst.sendPacket(packet, priority);
+ int count0 = Math.min(count, lines2x.size());
+
+ for (int i = 0; i < lines2x.size(); i++) {
+ KLALBRemoteLine krst =lines2x.get(i);
+ if(krst.getMonitor().getState()==MonitorData.ONLINE)
+ if(!packet.getSendRecord().contains(krst)) {
+ if(krst.getQueue().size()<3) {
packet.getSendRecord().add(krst);
+ krst.sendPacket(packet);
count0--;
if (count0 <= 0)
- break;
+ break loop;
+ }
+ }
}
- //tdb.putTime("sendPacket");
- //tdb.print();
- /*if(packet instanceof RSTPacket)
- new Exception().printStackTrace();*/
- }
- protected void removeFromSend(Inet6Address addr,KLALBPacket klalbPacket) {
- synchronized (lines) {
- for (Iterator iterator = lines.iterator(); iterator.hasNext();) {
- KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) iterator.next();
- klalbRemoteLine.remoeFromSendQueue(klalbPacket);
+ for (int i = 0; i < lines2x.size(); i++) {
+ KLALBRemoteLine krst =lines2x.get(i);
+ if(krst.getMonitor().getState()==MonitorData.ONLINE)
+ if(packet.getSendRecord().contains(krst)) {
+ if(krst.getQueue().size()<3) {
+ packet.getSendRecord().add(krst);
+ krst.sendPacket(packet);
+ count0--;
+ if (count0 <= 0)
+ break loop;
+ }
+ }
}
+ LockSupport.parkNanos(50000);
+ //tdb.putTime("sendfailed");
+ }
+ //tdb.putTime("sendsuccess");
+ //tdb.print();
+
+ /* List 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);
- public Timer getTimer() {
+ /*protected void removeFromSend(Inet6Address addr,KLALBPacket klalbPacket) {
+ 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;
}
+private Timer t2=new Timer("数据包粘包计时器", true);
+
+private List listens=new CopyOnWriteArrayList<>();
+
+ public Timer getNagleTimer() {
+ return t2;
+ }
+
public void registerToProxyTypeAs(String proxyname) {
MultipurposeSocketAddress.getSocketTypeRegister().put(proxyname+"_Stream",socketType);
//ProxyProfileEntry.getRegister().put(proxyname, this);
}
+
+
+ public List getListenSocketAddress() {
+ return listens;
+ }
+
/*@Override
diff --git a/src/org/kne/cloud/network/klalb/KLALBInputStream.java b/src/org/kne/cloud/network/klalb/KLALBInputStream.java
index 915a38e..f22fd71 100644
--- a/src/org/kne/cloud/network/klalb/KLALBInputStream.java
+++ b/src/org/kne/cloud/network/klalb/KLALBInputStream.java
@@ -24,68 +24,7 @@ public class KLALBInputStream extends DataInputStream {
throw new StreamCorruptedException("remote version is V"+bv+"."+sv+",not V2.0");
}
public KLALBPacket readPacket() throws IOException {
- return 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);
+ return KLALBPacket.readKLALBPacketFromStream(this);
}
+
}
diff --git a/src/org/kne/cloud/network/klalb/KLALBMain.java b/src/org/kne/cloud/network/klalb/KLALBMain.java
index 7624060..5c3d43e 100644
--- a/src/org/kne/cloud/network/klalb/KLALBMain.java
+++ b/src/org/kne/cloud/network/klalb/KLALBMain.java
@@ -1,46 +1,53 @@
package org.kne.cloud.network.klalb;
-import java.io.BufferedReader;
import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
import java.io.IOException;
import java.util.Iterator;
import java.util.Scanner;
-
-import org.kne.cloud.network.KLALBProxyConfigJsonExecuter;
-import org.kne.cloud.network.SocketToServiceProxy;
-import org.kne.cloud.network.SocketToSocketProxy;
+import org.kne.cloud.network.MultipurposeSocketAddress;
public class KLALBMain {
-
+ public static KLALBStateGUI2 ksg;
public static void main(String[] args) throws IOException {
System.out.println(CONST.klalb+" V"+CONST.klalbver);
Scanner scn=new Scanner(System.in);
File configJson=new File("klalbconfig.json");
- KLALBProxyConfigJsonExecuter kpcje=new KLALBProxyConfigJsonExecuter();
+ KLALBProxySystem kpcje=new KLALBProxySystem();
kpcje.loadConfigJson(configJson);
+ MultipurposeSocketAddress mpa=new MultipurposeSocketAddress("127.9.9.9", 49573);
+ kpcje.enableRemoteManagement(mpa);
+ System.out.println("远程管理端口已在"+mpa+"端口上开启");
while(true) {
String s=scn.next();
String[]sc=s.split(" ");
switch(sc[0]) {
+ case "?":
case "help":
- System.out.print("help:查看命令使用说明");
- System.out.print("state:查看线路状态");
+ 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 "monitor":
+ if(ksg==null)
+ ksg=kpcje.getKLALBGUI();
+ ksg.setVisible(true);
+ break;
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 iterator = kpcje.getKlalbController().getLines().iterator(); iterator.hasNext();) {
KLALBRemoteLine hostPort = iterator.next();
- System.out.println(hostPort .toString2());
+ System.out.println(hostPort .toString());
//System.out.println();
}
+ }
break;
case "stop":
System.exit(0);
@@ -49,7 +56,7 @@ public class KLALBMain {
kpcje.getKlalbController().reconnectImmediately();
break;
default:
- System.out.println("未知命令,请输入help以查询指令说明");
+ System.out.println("未知命令,请输入help以查询命令说明");
}
}
diff --git a/src/org/kne/cloud/network/klalb/KLALBOutputStream.java b/src/org/kne/cloud/network/klalb/KLALBOutputStream.java
index 457b344..3fcb13b 100644
--- a/src/org/kne/cloud/network/klalb/KLALBOutputStream.java
+++ b/src/org/kne/cloud/network/klalb/KLALBOutputStream.java
@@ -16,11 +16,7 @@ public class KLALBOutputStream extends DataOutputStream {
flush();
}
public void writePacket(KLALBPacket klb) throws IOException {
- writeKLALBPacketToStream(this, klb);
- }
- public static void writeKLALBPacketToStream(DataOutputStream out,KLALBPacket klb) throws IOException {
- out.write(klb.getType());
- klb.writeToStream(out);
- out.flush();
+ KLALBPacket.writeKLALBPacketToStream(this, klb);
}
+
}
diff --git a/src/org/kne/cloud/network/klalb/KLALBPacket.java b/src/org/kne/cloud/network/klalb/KLALBPacket.java
index 5f65c2d..13b2715 100644
--- a/src/org/kne/cloud/network/klalb/KLALBPacket.java
+++ b/src/org/kne/cloud/network/klalb/KLALBPacket.java
@@ -1,18 +1,31 @@
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.EOFException;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
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.concurrent.atomic.AtomicLong;
+import java.util.concurrent.locks.ReentrantLock;
-public abstract class KLALBPacket implements Sumable{
+public abstract class KLALBPacket implements Comparable{
public static final int PING=0;
public static final int PONG=1;
- public static final int SYNT=2;
- public static final int SACKT=3;
+ public static final int BWINF=2;
+ //public static final int SYNT=2;
+ //public static final int SACKT=3;
public static final int RST=4;
public static final int DATAT=5;
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 VADDRACK=12;
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) {
super();
- this.type = type;
+ header=headerbufferpool.borrow();
+ header.put((byte) type);
+ }
+ public KLALBPacket(int type, long priority) {
+ this(type);
+ this.priority=priority;
}
@Override
public String toString() {
- return "KLALBPacket [type=" + type + "]";
+ return "KLALBPacket [type=" + getType() + "]";
}
public int getType() {
- return type;
+ return header.get(0)&0xff;
}
private long sndtime,rcvtime;
- protected void writeToStream(DataOutput dto) throws IOException {
+
+
+
+ protected void writeToChannel(WritableByteChannel dto) throws IOException {
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();
+ header.limit(getHeaderSize());
+ while(header.hasRemaining()){
+ if(din.read(header)==-1) {
+ throw new EOFException();
+ }
+ }
+ }
+
+ protected int getHeaderSize() {
+ return 1;
}
public long getSndtime() {
return sndtime;
@@ -51,19 +99,150 @@ public abstract class KLALBPacket implements Sumable{
return rcvtime;
}
public long getLength() {
- return 1;
- }
- @Override
- public long getValue() {
- return getLength();
+ return getHeaderSize();
}
+ 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 sendRecord=new Vector<>();
+ @Override
+ public int compareTo(KLALBPacket o) {
+ if(priority>o.priority) {
+ return 1;
+ }else if(priorityo.sendseq) {
+ return 1;
+ }else if(sendseq sendRecord=new ArrayList<>(2);
+ private volatile boolean disposed;
+ private volatile ReentrantLock disposeLock=new ReentrantLock();
+ public boolean isDisposed() {
+ return disposed;
+ }
- public Vector getSendRecord() {
+ public List getSendRecord() {
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);
+ }
}
diff --git a/src/org/kne/cloud/network/klalb/KLALBPacketLink.java b/src/org/kne/cloud/network/klalb/KLALBPacketLink.java
index c47e8a0..03ae356 100644
--- a/src/org/kne/cloud/network/klalb/KLALBPacketLink.java
+++ b/src/org/kne/cloud/network/klalb/KLALBPacketLink.java
@@ -5,9 +5,14 @@ import java.net.SocketException;
public interface KLALBPacketLink {
public void writePacket(KLALBPacket kp) throws IOException;
+ public void flush() throws IOException;
public KLALBPacket readPacket()throws IOException;
public void close() throws IOException;
public boolean isClosed();
public void setSoTimeout(int val) throws SocketException;
public int getSoTimeout() throws SocketException;
+ @Override
+ public String toString();
+ public boolean isStream();
+
}
diff --git a/src/org/kne/cloud/network/klalb/KLALBProxySystem.java b/src/org/kne/cloud/network/klalb/KLALBProxySystem.java
new file mode 100644
index 0000000..63ffb87
--- /dev/null
+++ b/src/org/kne/cloud/network/klalb/KLALBProxySystem.java
@@ -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 proxys=new HashSet<>();
+ private KLALBController klalbController;
+ private KLALBRemoteManagement krm;
+ public Set 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();
+ LinkedHashMapmapb=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> iterator = stsp.getDetectedConnect().entrySet().iterator(); iterator.hasNext();) {
+ Entry proxy = (Entry) 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> iterator = stsp.getDetectedFactory().entrySet().iterator(); iterator.hasNext();) {
+ Entry proxy = (Entry) 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 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 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;
+ }
+}
diff --git a/src/org/kne/cloud/network/klalb/KLALBRemoteLine.java b/src/org/kne/cloud/network/klalb/KLALBRemoteLine.java
index e3abf54..c379d9f 100644
--- a/src/org/kne/cloud/network/klalb/KLALBRemoteLine.java
+++ b/src/org/kne/cloud/network/klalb/KLALBRemoteLine.java
@@ -1,6 +1,8 @@
package org.kne.cloud.network.klalb;
+import java.io.File;
import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
@@ -10,30 +12,62 @@ import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketTimeoutException;
+import java.nio.channels.UnresolvedAddressException;
+import java.time.Clock;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
+import java.util.PriorityQueue;
import java.util.UUID;
import java.util.Vector;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.LockSupport;
+import java.util.concurrent.locks.ReentrantLock;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
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.SpeedLimiter;
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{
-
+public class KLALBRemoteLine implements Comparable {
+
+ 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 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 getLocalVaddrSupplier() {
return localVaddrSupplier;
}
@@ -41,45 +75,44 @@ public class KLALBRemoteLine implements Comparable{
public void setLocalVaddrSupplier(Supplier localVaddrSupplier) {
this.localVaddrSupplier = localVaddrSupplier;
}
-
-
+
private volatile Inet6Address remoteVaddr;
- public Inet6Address getRemoteVaddr() throws SocketTimeoutException {
+
+ public Inet6Address getRemoteVaddr() {
return remoteVaddr;
}
-
+
+ private volatile AdjustedNanoClock adjnc = new AdjustedNanoClock();
+
public void waitForRemoteVaddrAvaliable(long timeout) throws SocketTimeoutException {
- long s=System.nanoTime();
- while(remoteVaddr==null) {
-
+ long s = System.nanoTime();
+ while (remoteVaddr == null) {
+
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
- if(System.nanoTime()-s>timeout*1000000)
+ if (System.nanoTime() - s > timeout * 1000000)
throw new SocketTimeoutException();
}
}
-
- public Monitor getMonitor() {
+
+ public SpeedAndTrafficAndDelayMonitorDataImpl getMonitor() {
return monitor;
}
+
public String toString() {
- return remoteVaddr+"\t"+monitor.toString()+"\t"+sumNextPacketCount();
+ return remoteVaddr + "\t" + monitor.toString();
}
-
- public String toString2() {
- return remoteVaddr+"\t"+monitor.toString2();
- }
- private Monitor monitor;
+
+ private SpeedAndTrafficAndDelayMonitorDataImpl monitor;
private volatile KLALBPacketLink kplink;
private MultipurposeSocketAddress bindAddress;
private MultipurposeSocketAddress socketAddress;
private Thread lthd;
-
-
+
public void setKplink(KLALBPacketLink kplink) {
this.kplink = kplink;
}
@@ -88,415 +121,554 @@ public class KLALBRemoteLine implements Comparable{
return kplink;
}
-
public MultipurposeSocketAddress getSocketAddress() {
return socketAddress;
}
-
-
public MultipurposeSocketAddress getBindAddress() {
return bindAddress;
}
- protected static KLALBPacketLink createLink(MultipurposeSocketAddress bindAddress,MultipurposeSocketAddress mpa) throws IOException {
- if(mpa.isStream()) {
- if(bindAddress!=null) {
- return new StreamKLALBPacketLink(mpa.connectSocket(InetAddress.getByName( bindAddress.getHost()),bindAddress.getPort()));
- }else {
- return new StreamKLALBPacketLink(mpa.connectSocket());
+ protected static KLALBPacketLink createLink(MultipurposeSocketAddress bindAddress, MultipurposeSocketAddress mpa)
+ throws IOException {
+ if (mpa.isStream()) {
+ if (mpa.supportNIO()) {
+ if (bindAddress != null) {
+ 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 ) {
- this.socketAddress=mpa;
- this.bindAddress=bindaddr;
- this.monitor=monitor;
- monitor.setName(mpa.toString());
+ public KLALBRemoteLine(MultipurposeSocketAddress mpa) {
+ this(mpa, new SpeedAndTrafficAndDelayMonitorDataImpl());
+ }
+
+ 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) {
- this(mpa,bindaddr,new Monitor());
+ this(mpa, bindaddr, new SpeedAndTrafficAndDelayMonitorDataImpl());
}
- PrintStream pw;
- private void startRecord() {
- try {
- pw=new PrintStream(UUID.randomUUID()+".csv");
- pw.println("时间,状态,上传速度,下载速度,上传延迟,下载延迟,往返延迟,抖动");
- ThreadTool.makePDaemonThreadIfSupport("BigData Record", ()->{
- while(true) {
+ PrintStream pw;
+
+ 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 {
- Thread.sleep(1000);
+ Thread.sleep(100);
} catch (InterruptedException e) {
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();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
-
- private void endRecord() {
- if(pw!=null)
- pw.close();
- }
-
- protected void startIO() {
- ThreadTool.makePDaemonThreadIfSupport("远程接收线程", () -> {
- //startRecord();
- while(true) {
- try {
- monitor.setState(Monitor.CONNECTING);
- if(socketAddress==null) {
- if(kplink.isClosed()) {
- monitor.setState(Monitor.OFFLINE);
- closed=true;
- break;
- }
- }else {
- try {
- kplink=createLink(bindAddress,socketAddress);
- }catch(BindException be){
- //be.printStackTrace();
- close();
- throw be;
- }
- }
- kplink.setSoTimeout(10000);
- Thread t=ThreadTool.makePDaemonThreadIfSupport("远程发送线程", () -> {
+ private SpeedLimiter congress = new SpeedLimiter();
+ private long congressSpeed = 0;
+ private double increaceFactor = 1.2;
+
+ protected void startIO() {
+ ThreadTool.makeVDaemonThreadIfSupport("远程接收线程", () -> {
+ while (true) {
try {
- writePacketToKPL(new VADDRREQPacket());
- writePacketToKPL(new VADDRREQPacket());
- writePacketToKPL(new VADDRREQPacket());
- while ((!kplink.isClosed())&&(!closed)) {
- if(checkPingTime()) {
- writePacketToKPL(new PINGPacket(System.nanoTime()));
- }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);
+
+ monitor.setState(MonitorData.CONNECTING);
+ if (socketAddress == null) {
+ if (kplink.isClosed()) {
+ close();
+ break;
}
+ } 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();
}
- } catch (IOException e) {
+ } catch (IOException | UnresolvedAddressException e) {
+ if (debug)
+ e.printStackTrace();
+ } catch (InterruptedException e) {
e.printStackTrace();
} finally {
+ monitor.setState(MonitorData.OFFLINE);
+ pressure = false;
try {
- kplink.close();
+ if (kplink != null)
+ 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;
- 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;
+ KLALBPacket pack;
+ while((pack=sendDequeList.poll())!=null) {
+ try {
+ if(remoteVaddr!=null) {
+ klalbController.sendPacketToAddress(remoteVaddr, pack);
+ if(debug)
+ System.out.println("RETRY:"+pack);
}
- if(rcvDelayFactor==Long.MIN_VALUE) {
- 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;
+ } catch (IOException e) {
+ }
}
- Thread.yield();
}
- } catch (IOException e) {
- e.printStackTrace();
- } catch (InterruptedException e) {
- e.printStackTrace();
- } finally {
- monitor.setState(Monitor.OFFLINE);
- try {
- if(kplink!=null)
- kplink.close();
- } catch (IOException e) {
- e.printStackTrace();
+
+ if (closed) {
+ break;
}
-
+ // 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();
-
+
+ }
+
+ private void flushKPL() throws IOException {
+ kplink.flush();
}
-
-
-
private KLALBPacket readPacketFromKPL() throws IOException {
- KLALBPacket packet=kplink.readPacket();
- /*if(!(packet instanceof PINGPacket) )
- if(!(packet instanceof PONGPacket) )
- System.out.println("RX:" + packet);*/
- if(packet!=null)
- monitor.getInTrafficAL().addAndGet(packet.getLength());
+ KLALBPacket packet = kplink.readPacket();
+ if (showpacket) {
+ if (!(packet instanceof PINGPacket))
+ if (!(packet instanceof PONGPacket))
+ System.out.println("RX:" + packet);
+ }
+ if (packet != null) {
+ monitor.getInTrafficAL().addAndGet(packet.getLength());
+ if (klalbController != null)
+ klalbController.getLinkMonitor().getInTrafficAL().addAndGet(packet.getLength());
+ }
return packet;
}
+
private void writePacketToKPL(KLALBPacket packet) throws IOException {
monitor.getOutTrafficAL().addAndGet(packet.getLength());
+ if (klalbController != null)
+ klalbController.getLinkMonitor().getOutTrafficAL().addAndGet(packet.getLength());
kplink.writePacket(packet);
- /*if(!(packet instanceof PINGPacket) )
- if(!(packet instanceof PONGPacket) )
- System.err.println("TX:" + packet);*/
+ if (showpacket) {
+ if (!(packet instanceof PINGPacket))
+ if (!(packet instanceof PONGPacket))
+ System.err.println("TX:" + packet);
+ }
}
public void close() {
- closed=true;
+ closed = true;
+ monitor.setState(MonitorData.OFFLINE);
+ pressure = false;
try {
- if(kplink!=null)
- kplink.close();
+ if (kplink != null)
+ kplink.close();
} catch (IOException e) {
e.printStackTrace();
}
}
+
public boolean isClosed() {
return closed;
}
-
+
+ private volatile long timeTurnSleep = 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() {
long cu = System.nanoTime();
- if (cu - time > pingInterval) {
+ if (cu - time > ((System.nanoTime() - timeTurnSleep > 500000000) ? pingIntervalSleep
+ : Math.min(pingIntervalSleep, pingInterval))) {
time = cu;
return true;
} else {
return false;
}
}
-
-
-
+
private volatile BiConsumer rec;
- //private Object lock=new Object();
private volatile Thread tlock;
- private List> sendDequeList =new ArrayList>();
- {
- for(int i=0;i<12;i++) {
- sendDequeList.add(new SumQueue(new ConcurrentLinkedQueue<>()));
- }
+
+ private ConcurrentLinkedQueue IsendDequeList = new ConcurrentLinkedQueue();
+
+ private PriorityBlockingQueue sendDequeList = new PriorityBlockingQueue();
+
+ public PriorityBlockingQueue getQueue() {
+ return sendDequeList;
}
- private KLALBPacket getNextPacket() {
- for (Iterator> iterator = sendDequeList.iterator(); iterator.hasNext();) {
- SumQueue queue = (SumQueue) iterator.next();
- 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> iterator = sendDequeList.iterator(); iterator.hasNext();) {
- SumQueue queue = (SumQueue) iterator.next();
- i+=queue.getSumValue();
- }
- return i;
- }
- private long sumNextPacketCount() {
- long i=0;
- for (Iterator> iterator = sendDequeList.iterator(); iterator.hasNext();) {
- SumQueue queue = (SumQueue) 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);
+
+ protected void sendPacket(KLALBPacket blk) {
+ sendDequeList.add(blk);
LockSupport.unpark(tlock);
}
- public void setPacketReceiver(BiConsumer rec) {
+ private void sendIPacket(KLALBPacket blk) {
+ IsendDequeList.add(blk);
+ LockSupport.unpark(tlock);
+ }
+
+ public void setPacketReceiver(BiConsumer rec) {
this.rec = rec;
}
-
-
- public void remoeFromSendQueue(KLALBPacket klalbPacket) {
- for (Iterator> iterator = sendDequeList.iterator(); iterator.hasNext();) {
- SumQueue queue = iterator.next();
- queue.removeIf((x)->{
- return x.equals(klalbPacket);
- });
- }
- }
-
- public long statLengthBefore(int priority) {
- AtomicLong al=new AtomicLong();
- int n=0;
- for (Iterator> iterator = sendDequeList.iterator(); iterator.hasNext();n++) {
- if(n>priority) {
- break;
+ /*public void remoeFromSendQueue(KLALBPacket klalbPacket) {
+ sendDequeList.remove(klalbPacket);
+ }*/
+
+ public long statLengthBefore(long l) {
+ AtomicLong al = new AtomicLong();
+ for (Iterator iterator = sendDequeList.iterator(); iterator.hasNext();) {
+ KLALBPacket queue = iterator.next();
+ if (queue.getPriority() <= l) {
+ al.addAndGet(queue.getLength());
}
- SumQueue queue = iterator.next();
- al.addAndGet(queue.getSumValue());
-
+
}
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;
- public void runPredict(KLALBPacket curr,int priority) {
- predictTime=sndDelayFactor;
- //System.out.println(this+" "+sndDelayFactor);
- long al=0;
- al=statLengthBefore(priority);
- long speed=getMonitor(). getOutSpeed();
- if(speed==0) {
- if(al>0) {
- predictTime=Long.MAX_VALUE;
- }
- }else {
- predictTime+=al*1000000000L/speed;
- }
+
+ public void runPredict() {
+ //predictTime = monitor.getOutDelayPredicted();
+ predictTime=monitor.getOutDelay();
+ /*
+ * long al=0; al=statLengthBefore(5); long speed=getMonitor().getOutSpeedAvg();
+ * // spdlmt.setLimitspeed(speed*2+65536); if(speed==0) { if(al>0) {
+ * predictTime=Long.MAX_VALUE; } }else { predictTime+=al*1000000000L/speed; }
+ */
}
+
@Override
public int compareTo(KLALBRemoteLine o2) {
- long t1=this.predictTime;
- long t2=o2.predictTime;
- if(t1>t2) {
+ long t1 = this.predictTime;
+ long t2 = o2.predictTime;
+ if (t1 > t2) {
return 1;
- }else if(t1 {
+ 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;
+ }
+
}
diff --git a/src/org/kne/cloud/network/klalb/KLALBRemoteManagement.java b/src/org/kne/cloud/network/klalb/KLALBRemoteManagement.java
new file mode 100644
index 0000000..a9d6e56
--- /dev/null
+++ b/src/org/kne/cloud/network/klalb/KLALBRemoteManagement.java
@@ -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();
+ Listlineslist= klalbProxySystem.getKlalbController().getLines();
+ synchronized (lineslist) {
+ for (Iterator 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();
+ Listselflineslist=klalbProxySystem.getKlalbController().getSelflineTable();
+ synchronized (selflineslist) {
+ for (Iterator 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();
+ Listselflineslist2=klalbProxySystem.getKlalbController().getSelflineTable();
+ synchronized (selflineslist2) {
+ selflineslist2.add(new MultipurposeSocketAddress(mips));
+ }
+ break;
+ case "REMOVESELFLINE":
+ String mipsr=jreq.getAsJsonPrimitive("ipport").getAsString();
+ Listselflineslist21=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 pxy=klalbProxySystem.getProxys();
+ synchronized (pxy) {
+ for (Iterator 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 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();
+ }
+}
diff --git a/src/org/kne/cloud/network/klalb/KLALBStateGUI.java b/src/org/kne/cloud/network/klalb/KLALBStateGUI.java
index bae5f47..d26871a 100644
--- a/src/org/kne/cloud/network/klalb/KLALBStateGUI.java
+++ b/src/org/kne/cloud/network/klalb/KLALBStateGUI.java
@@ -1,10 +1,8 @@
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;
@@ -13,34 +11,18 @@ 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.swing.JButton;
-import javax.swing.JComboBox;
-import javax.swing.JOptionPane;
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.YScrollPane;
-import javax.swing.JProgressBar;
public class KLALBStateGUI extends XFrame {
private BufferedImage bi;
@@ -50,6 +32,10 @@ public class KLALBStateGUI extends XFrame {
private SystemTray st;
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 {
setResizable(false);
try {
@@ -59,9 +45,14 @@ public class KLALBStateGUI extends XFrame {
}
if(bi!=null)
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));
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")
- KLALBStateGUI kcg=new KLALBStateGUI(new KLALBController(),"KNE云网络负载均衡客户端 V2.0");
- Thread.sleep(10000);
- kcg.close();
+ KLALBStateGUI kcg=new KLALBStateGUI(new KLALBController());
+ kcg.setVisible(true);
+ //Thread.sleep(10000);
+ //kcg.close();
}
}
diff --git a/src/org/kne/cloud/network/klalb/KLALBStateGUI2.java b/src/org/kne/cloud/network/klalb/KLALBStateGUI2.java
new file mode 100644
index 0000000..f6a4275
--- /dev/null
+++ b/src/org/kne/cloud/network/klalb/KLALBStateGUI2.java
@@ -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();
+ }
+}
diff --git a/src/org/kne/cloud/network/klalb/KLALBUtils.java b/src/org/kne/cloud/network/klalb/KLALBUtils.java
index f0e314f..e231ba9 100644
--- a/src/org/kne/cloud/network/klalb/KLALBUtils.java
+++ b/src/org/kne/cloud/network/klalb/KLALBUtils.java
@@ -13,7 +13,9 @@ public class KLALBUtils {
ByteArrayOutputStream bos=new ByteArrayOutputStream(8);
DataOutputStream dos=new DataOutputStream(bos);
try {
- dos.writeLong(uuid.getMostSignificantBits());
+ long l=uuid.getMostSignificantBits();
+ l=(l&0x0000FFFFFFFFFFFFL)|0x2486000000000000L;
+ dos.writeLong(l);
dos.writeLong(uuid.getLeastSignificantBits());
dos.close();} catch (IOException e) {
// TODO 自动生成的 catch 块
@@ -31,6 +33,21 @@ public class KLALBUtils {
System.out.println(uuidToIP(new UUID(-1,-1)));
}
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) {
return format( v/(1024.0*1024.0*1024.0*1024.0*1024.0))+"P";
}else if(v>=1024L*1024*1024*1024) {
diff --git a/src/org/kne/cloud/network/klalb/KLALBVirtualServerSocket.java b/src/org/kne/cloud/network/klalb/KLALBVirtualServerSocket.java
index 9d1af6d..f451354 100644
--- a/src/org/kne/cloud/network/klalb/KLALBVirtualServerSocket.java
+++ b/src/org/kne/cloud/network/klalb/KLALBVirtualServerSocket.java
@@ -6,17 +6,26 @@ import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
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.VirtualSocket;
+import org.kne.cloud.network.VirtualSocketImpl;
public class KLALBVirtualServerSocket extends VirtualServerSocket {
private KLALBController controler;
+ protected ServerSocketChannel channel;
public KLALBVirtualServerSocket(KLALBController controler) throws IOException {
super(controler.createVirtualImpl());
this.controler=controler;
}
+ @Override
+ protected KLALBVirtualSocketImpl getVirtualImpl() {
+ return (KLALBVirtualSocketImpl) super.getVirtualImpl();
+ }
+
public KLALBVirtualServerSocket(KLALBController controler,int port) throws IOException {
this(controler,port, 50, null);
}
@@ -52,4 +61,9 @@ public class KLALBVirtualServerSocket extends VirtualServerSocket {
return s2;
}
+ @Override
+ public ServerSocketChannel getChannel() {
+ return channel;
+ }
+
}
diff --git a/src/org/kne/cloud/network/klalb/KLALBVirtualServerSocketChannel.java b/src/org/kne/cloud/network/klalb/KLALBVirtualServerSocketChannel.java
new file mode 100644
index 0000000..1841b66
--- /dev/null
+++ b/src/org/kne/cloud/network/klalb/KLALBVirtualServerSocketChannel.java
@@ -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 getOption(SocketOption name) throws IOException {
+ // TODO 自动生成的方法存根
+ return null;
+ }
+
+ @Override
+ public Set> supportedOptions() {
+ // TODO 自动生成的方法存根
+ return null;
+ }
+
+ @Override
+ public ServerSocketChannel bind(SocketAddress local, int backlog) throws IOException {
+ serversocket.bind(local, backlog);
+ return this;
+ }
+
+ @Override
+ public ServerSocketChannel setOption(SocketOption 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");
+ }
+ }
+
+
+
+}
diff --git a/src/org/kne/cloud/network/klalb/KLALBVirtualServerSocketChannelFactory.java b/src/org/kne/cloud/network/klalb/KLALBVirtualServerSocketChannelFactory.java
new file mode 100644
index 0000000..909cc3d
--- /dev/null
+++ b/src/org/kne/cloud/network/klalb/KLALBVirtualServerSocketChannelFactory.java
@@ -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;
+ }
+
+}
diff --git a/src/org/kne/cloud/network/klalb/KLALBVirtualSocket.java b/src/org/kne/cloud/network/klalb/KLALBVirtualSocket.java
index 6a4aa95..ca6604b 100644
--- a/src/org/kne/cloud/network/klalb/KLALBVirtualSocket.java
+++ b/src/org/kne/cloud/network/klalb/KLALBVirtualSocket.java
@@ -2,12 +2,20 @@ package org.kne.cloud.network.klalb;
import java.io.IOException;
import java.net.*;
+import java.nio.channels.SocketChannel;
import org.kne.cloud.network.VirtualSocket;
+import org.kne.cloud.network.VirtualSocketImpl;
public class KLALBVirtualSocket extends VirtualSocket {
+ @Override
+ protected KLALBVirtualSocketImpl getVirtualImpl() {
+ return (KLALBVirtualSocketImpl) super.getVirtualImpl();
+ }
+
private KLALBController controler;
+ protected SocketChannel channel;
public KLALBVirtualSocket(KLALBController controler) throws SocketException {
super(controler.createVirtualImpl());
@@ -70,5 +78,19 @@ public class KLALBVirtualSocket extends VirtualSocket {
public void associateSocket(Socket associateSocket) throws IOException {
((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();
+ }
+
+
+
}
\ No newline at end of file
diff --git a/src/org/kne/cloud/network/klalb/KLALBVirtualSocketChannel.java b/src/org/kne/cloud/network/klalb/KLALBVirtualSocketChannel.java
new file mode 100644
index 0000000..3c52e10
--- /dev/null
+++ b/src/org/kne/cloud/network/klalb/KLALBVirtualSocketChannel.java
@@ -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 getOption(SocketOption name) throws IOException {
+ // TODO 自动生成的方法存根
+ return null;
+ }
+
+ @Override
+ public Set> supportedOptions() {
+ // TODO 自动生成的方法存根
+ return null;
+ }
+
+ @Override
+ public SocketChannel bind(SocketAddress local) throws IOException {
+ socket.bind(local);
+ return this;
+ }
+
+ @Override
+ public SocketChannel setOption(SocketOption 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);
+ }
+
+}
diff --git a/src/org/kne/cloud/network/klalb/KLALBVirtualSocketChannelFactory.java b/src/org/kne/cloud/network/klalb/KLALBVirtualSocketChannelFactory.java
new file mode 100644
index 0000000..c85d6ac
--- /dev/null
+++ b/src/org/kne/cloud/network/klalb/KLALBVirtualSocketChannelFactory.java
@@ -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;
+ }
+
+}
diff --git a/src/org/kne/cloud/network/klalb/KLALBVirtualSocketImpl.java b/src/org/kne/cloud/network/klalb/KLALBVirtualSocketImpl.java
index b19280e..29717aa 100644
--- a/src/org/kne/cloud/network/klalb/KLALBVirtualSocketImpl.java
+++ b/src/org/kne/cloud/network/klalb/KLALBVirtualSocketImpl.java
@@ -22,6 +22,11 @@ import java.net.SocketImpl;
import java.net.SocketOptions;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
+import java.nio.ByteBuffer;
+import java.nio.channels.Channels;
+import java.nio.channels.ReadableByteChannel;
+import java.nio.channels.SocketChannel;
+import java.nio.channels.WritableByteChannel;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.BlockingQueue;
@@ -44,12 +49,15 @@ import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;
+import java.util.zip.GZIPInputStream;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;
import org.kne.acclerate.FastLib;
+import org.kne.cloud.network.SpeedLimiter;
import org.kne.cloud.network.ThreadTool;
import org.kne.cloud.network.VirtualSocketImpl;
+import org.kne.cloud.network.monitor.SpeedAndTrafficAndDelayMonitorDataImpl;
import org.kne.debug.TimeDebugger;
import org.kne.io.Data;
@@ -71,6 +79,9 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl
}
*/
+
+ private SpeedAndTrafficAndDelayMonitorDataImpl socketMonitor=new SpeedAndTrafficAndDelayMonitorDataImpl();
+
private KLALBController controller;
protected int getInputchachesize() {
@@ -89,8 +100,14 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl
this.outputchachesize = outputchachesize;
}
- private volatile int inputchachesize = LIMIT * 2000;
- private volatile int outputchachesize = LIMIT * 200;
+ //private Speed
+
+ private volatile int inputchachesize = MTU * 2000;
+ private volatile int outputchachesize = MTU * 50;
+ private volatile int reallimit = MTU * 40;
+ //private SpeedLimiter spdlmt=new SpeedLimiter(1024*1024);
+ //private volatile double maxutilization=0.8;
+
private volatile boolean nodelay=false;
private volatile long delaytime=1;
@@ -101,8 +118,8 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl
public void setDelaytime(long delaytime) {
this.delaytime = delaytime;
}
- protected Inet6Address remoteaddr;
- protected Inet6Address localaddr;{
+ protected volatile Inet6Address remoteaddr;
+ protected volatile Inet6Address localaddr;{
try {
localaddr=(Inet6Address) Inet6Address.getByName("::0");
} catch (UnknownHostException e) {
@@ -110,30 +127,43 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl
}
}
//private CountDownLatch reseted=new CountDownLatch(1);
- private BlockingQueue