稳定性升级

This commit is contained in:
Administrator
2023-07-26 21:30:00 +08:00
parent 585b7c5fe6
commit 722ab9710f
30 changed files with 720 additions and 158 deletions
+2 -2
View File
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="src" path="src"/>
<classpathentry combineaccessrules="false" kind="src" path="/KNElib"/>
<classpathentry kind="lib" path="lib/gson-2.1.jar"/>
<classpathentry kind="lib" path="lib/javassist.jar" sourcepath="C:/Users/ADMINI~1/AppData/Local/Temp/1/.org.sf.feeling.decompiler1686963856070/source/javassist-3.29.2-GA-sources.jar"/>
<classpathentry combineaccessrules="false" kind="src" path="/KNElib"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk-19"/>
<classpathentry kind="output" path="bin"/>
</classpath>
+3 -3
View File
@@ -1,9 +1,9 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.targetPlatform=19
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.compliance=19
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
@@ -12,4 +12,4 @@ org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
org.eclipse.jdt.core.compiler.release=disabled
org.eclipse.jdt.core.compiler.source=1.8
org.eclipse.jdt.core.compiler.source=19
Binary file not shown.
+3
View File
@@ -0,0 +1,3 @@
#Tue Jul 25 19:03:09 CST 2023
local=0.0.0.0\:35000
server=127.0.0.1\:4569
+3
View File
@@ -0,0 +1,3 @@
virtualip=67c:72ce:765e:4db1:a02e:92fa:1959:29eb
bind=0.0.0.0:4569
local=127.0.0.1:36555
+1 -1
View File
@@ -1,3 +1,3 @@
virtualip=67c:72ce:765e:4db1:a02e:92fa:1959:29eb
bind=0.0.0.0:4569
local=127.0.0.1:5212
local=127.0.0.1:36555
+19
View File
@@ -0,0 +1,19 @@
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
192.168.0.233:4569
192.168.1.233:4569
+20
View File
@@ -0,0 +1,20 @@
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
192.168.0.233:4569
192.168.1.233:4569
cn-he-plc-2.openfrp.top:4569
@@ -0,0 +1,28 @@
package org.kne.cloud.network.klalb;
import java.util.concurrent.ConcurrentLinkedQueue;
public class ByteArrayRecycle {
private ConcurrentLinkedQueue<byte[]>rec=new ConcurrentLinkedQueue<>();
private int capacity;
private int length;
public ByteArrayRecycle(int capacity, int length) {
super();
this.capacity = capacity;
this.length = length;
}
public synchronized void recycle(byte[]b) {
if(b.length!=length)
throw new IllegalArgumentException("wrong length");
if(rec.size()<capacity) {
rec.add(b);
}
}
public synchronized byte[] create() {
byte[]b=rec.poll();
if(b==null) {
b=new byte[length];
}
return b;
}
}
@@ -0,0 +1,34 @@
package org.kne.cloud.network.klalb;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.zip.Deflater;
import java.util.zip.DeflaterInputStream;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;
import org.kne.cloud.network.mport.SocketBridge;
public class CompressedSocketBridge extends SocketBridge {
public CompressedSocketBridge(Socket a, Socket b) throws IOException {
super(a, b);
}
@Override
protected OutputStream getBOUT() throws IOException {
return new DeflaterOutputStream(super.getBOUT(), new Deflater(Deflater.BEST_COMPRESSION, true), true) ;
}
@Override
protected InputStream getBIN() throws IOException {
return new InflaterInputStream(super.getBIN(), new Inflater(true)) ;
}
}
@@ -5,20 +5,23 @@ import java.io.DataOutput;
import java.io.IOException;
public class DATATPacket extends KLALBPacket {
public static final ByteArrayRecycle arrayRecycle=new ByteArrayRecycle(100,65535);
@Override
public long getLength() {
return super.getLength()+18+data.length;
return super.getLength()+18+size;
}
private int sport,dport;
private long number;
private int size;
private byte[]data;
public DATATPacket(int sport,int dport,long number,byte[]data) {
public DATATPacket(int sport,int dport,long number,byte[]data,int size) {
super(DATAT);
this.sport=sport;
this.dport=dport;
this.number=number;
this.data=data;
this.size=size;
}
public DATATPacket() {
@@ -43,7 +46,7 @@ public class DATATPacket extends KLALBPacket {
@Override
public String toString() {
return "DATAT "+sport+"->"+dport+" "+number+"["+data.length+"]";
return "DATAT "+sport+"->"+dport+" "+number+"["+size+"]";
}
@Override
@@ -52,8 +55,8 @@ public class DATATPacket extends KLALBPacket {
dto.writeInt(sport);
dto.writeInt(dport);
dto.writeLong(number);
dto.writeChar(data.length);
dto.write(data);
dto.writeChar(size);
dto.write(data,0,size);
}
@Override
@@ -62,7 +65,11 @@ public class DATATPacket extends KLALBPacket {
sport=din.readInt();
dport=din.readInt();
number=din.readLong();
data=new byte[din.readChar()];
din.readFully(data);
size=din.readChar();
data=arrayRecycle.create();
din.readFully(data,0,size);
}
public int getSize() {
return size;
}
}
@@ -264,15 +264,21 @@ public class KLALBController {
if (l == null || l.isEmpty()) {
throw new NoRouteToHostException("address unreachable: " + addr);
}
int count0 = Math.min(count, l.size());
List<KLALBRemoteSocket> l2 = (List<KLALBRemoteSocket>) ((ArrayList<KLALBRemoteSocket>) l).clone();
LineDecitionComparator ldc = new LineDecitionComparator(l2, priority);
l2.removeAll(packet.getSendRecord());
if(l2.isEmpty()) {
l2 = (List<KLALBRemoteSocket>) ((ArrayList<KLALBRemoteSocket>) l).clone();
}
int count0 = Math.min(count, l2.size());
LineDecitionComparator ldc = new LineDecitionComparator(l2,packet, priority);
Collections.sort(l2,ldc);
//System.out.println(l2);
for (Iterator<KLALBRemoteSocket> iterator = l2.iterator(); iterator.hasNext();) {
KLALBRemoteSocket krst = (KLALBRemoteSocket) iterator.next();
krst.sendPacket(packet, priority);
packet.getSendRecord().add(krst);
count0--;
Thread.yield();
if (count0 <= 0)
break;
}
@@ -6,6 +6,7 @@ import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.Vector;
public abstract class KLALBPacket{
public static final int PING=0;
@@ -40,5 +41,11 @@ public abstract class KLALBPacket{
public long getLength() {
return 1;
}
private Vector<KLALBRemoteSocket> sendRecord=new Vector<>();
public Vector<KLALBRemoteSocket> getSendRecord() {
return sendRecord;
}
}
@@ -35,13 +35,12 @@ public KLALBRemoteSocket(Socket socket) {
public KLALBRemoteSocket(Socket socket,Monitor m) {
super(socket,m);
try {
socket.setSendBufferSize(32768);
socket.setReceiveBufferSize(65535);
//socket.setSendBufferSize(32768);
//socket.setReceiveBufferSize(65535);
//System.out.println(socket.getSendBufferSize()+" "+socket.getReceiveBufferSize());
socket.setTcpNoDelay(true);
socket.setSoTimeout(10000);
} catch (SocketException e1) {
// TODO 自动生成的 catch 块
e1.printStackTrace();
}
ThreadTool.makeVDaemonThreadIfSupport("远程接收线程", () -> {
@@ -49,20 +48,20 @@ public KLALBRemoteSocket(Socket socket) {
while (!isClosed()) {
KLALBPacket kpp = getInputStream().readPacket();
//System.out.println("RX:" + kpp);
if(kpp instanceof PINGPacket) {
sendPacket(new PONGPacket(((PINGPacket) kpp).getTime()), 65540);
}else if(kpp instanceof PONGPacket) {
PONGPacket png=(PONGPacket) kpp;
getMonitor().updateLatency (System.nanoTime()- png.getTime());
try {
socket.setSoTimeout(1100);
socket.setSoTimeout(600);
} catch (SocketException e1) {
// TODO 自动生成的 catch 块
e1.printStackTrace();
}
}else {
System.out.println("RX:" + kpp);
if(kpp instanceof VADDRPacket) {
remoteVaddr=((VADDRPacket) kpp).getVaddr();
}
@@ -94,15 +93,19 @@ public KLALBRemoteSocket(Socket socket) {
PQItem pqi=sendQueue.poll();
if(pqi!=null) {
KLALBPacket kpp=pqi.getPacket();
//if(!(kpp instanceof PONGPacket))
//System.out.println("TX:" + kpp);
if(!(kpp instanceof PONGPacket))
System.out.println("TX:" + kpp);
if(kpp instanceof PONGPacket) {
PONGPacket pp=(PONGPacket) kpp;
pp.redeltaTime(System.nanoTime()-pqi.getAddtime());
}
getOutputStream().writePacket(kpp);
//System.out.println(sendQueue.size());
}else {
Thread.sleep(1);
synchronized (sendQueue) {
sendQueue.wait(10);
}
//Thread.sleep(1);
}
}
}
@@ -117,7 +120,6 @@ public KLALBRemoteSocket(Socket socket) {
}
}
}).start();
}
@@ -178,6 +180,9 @@ public KLALBRemoteSocket(Socket socket) {
public void sendPacket(KLALBPacket kp,int priority) {
sendQueue.add(new PQItem(kp, priority));
synchronized (sendQueue) {
sendQueue.notifyAll();
}
}
public void setPacketReceiver(Consumer<KLALBPacket> rec) {
@@ -194,11 +199,11 @@ public KLALBRemoteSocket(Socket socket) {
super.close();
sendQueue.forEach((x)->{
try {
//System.out.println("断线重发");
controller.sendPacketToAddress(remoteVaddr, x.getPacket(), x.getPriority()+1);
} catch (NoRouteToHostException e) {
}
});
}
@Override
@@ -31,12 +31,17 @@ import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicReferenceArray;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;
import org.kne.cloud.network.mport.VirtualSocketImpl;
import org.kne.io.Data;
import java.util.*;
public class KLALBVirtualSocketImpl extends SocketImpl {
public class KLALBVirtualSocketImpl extends VirtualSocketImpl {
private KLALBController controller;
protected int getInputchachesize() {
@@ -55,8 +60,19 @@ public class KLALBVirtualSocketImpl extends SocketImpl {
this.outputchachesize = outputchachesize;
}
private int inputchachesize = 5773 * 100;
private int outputchachesize = 5773 * 100;
private volatile int inputchachesize = LIMIT * 500;
private volatile int outputchachesize = LIMIT * 200;
private volatile boolean nodelay=false;
private volatile long delaytime=1;
public long getDelaytime() {
return delaytime;
}
public void setDelaytime(long delaytime) {
this.delaytime = delaytime;
}
private Inet6Address bindaddr;{
try {
bindaddr=(Inet6Address) Inet6Address.getByName("::0");
@@ -77,15 +93,20 @@ public class KLALBVirtualSocketImpl extends SocketImpl {
try {
sendlist.get(i).check(i);
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
try {
close();
} catch (IOException e1) {
e1.printStackTrace();
}
break;
}
}
}
}
}
private boolean succeed, refused;
private volatile boolean succeed, refused;
protected boolean isListening() {
return backlogQueue != null;
@@ -93,7 +114,7 @@ public class KLALBVirtualSocketImpl extends SocketImpl {
private List<DATATPacket> inputchache = new ArrayList<>();
private long inputcount = 0;
private boolean avaliable = true;
private volatile boolean avaliable = true;
private BiConsumer<Inet6Address, KLALBPacket> packReceiver = new BiConsumer<Inet6Address, KLALBPacket>() {
@Override
@@ -104,15 +125,15 @@ public class KLALBVirtualSocketImpl extends SocketImpl {
if (backlogQueue.offer(new InetSocketAddress(from, ((SYNTPacket) u).getSport()))) {
controller.sendPacketToAddress(from,
new SACKTPacket(localport, ((SYNTPacket) u).getSport()), 65537);
new SACKTPacket(localport, ((SYNTPacket) u).getSport()), 65537,2);
} else {
controller.sendPacketToAddress(from, new RSTPacket(localport, ((SYNTPacket) u).getSport()),
65537);
65537,2);
}
} else {
controller.sendPacketToAddress(from, new RSTPacket(localport, ((SYNTPacket) u).getSport()),
65537);
65537,2);
}
} else if (u instanceof SACKTPacket) {
if (connecting) {
@@ -148,23 +169,34 @@ public class KLALBVirtualSocketImpl extends SocketImpl {
if (kkb == null)
break;
sendDeque.add(kkb);
synchronized (sendDeque) {
sendDeque.notifyAll();
}
inputcount++;
}
}
}
controller.sendPacketToAddress(from, new ACKTPacket(dtp.getDport(), dtp.getSport(), dtp.getNumber(),
countInputBytes() < inputchachesize), 32768,2);
countInputBytes() < inputchachesize), 32768,1);
} else if (u instanceof ACKTPacket) {
ACKTPacket ackt = (ACKTPacket) u;
avaliable = ackt.isAvaliable();
AtomicReference<KLALBPacket>kl=new AtomicReference<>();
AtomicReference<DATATPacket>kl=new AtomicReference<>();
synchronized (sendlist) {
sendlist.removeIf((tsk)->{
boolean b=tsk.getPacket().getNumber()==ackt.getNumber();
if(b)
kl.set(tsk.getPacket());
return b;
});
sendlist.notifyAll();
}
if(kl.get()!=null) {
controller.removeFromSend(from,kl.get());
DATATPacket.arrayRecycle.recycle(kl.get().getData());
}
}
} catch (IOException e) {
e.printStackTrace();
@@ -177,14 +209,14 @@ public class KLALBVirtualSocketImpl extends SocketImpl {
private int countInputBytes() {
AtomicInteger i = new AtomicInteger(0);
sendDeque.forEach((c) -> {
i.addAndGet(c.getData().length);
i.addAndGet(c.getSize());
});
return i.get();
}
private int countOutputBytes() {
AtomicInteger i = new AtomicInteger(0);
sendlist.forEach((c) -> {
i.addAndGet(c.getPacket().getData().length);
i.addAndGet(c.getPacket().getSize());
});
return i.get();
}
@@ -204,23 +236,34 @@ public class KLALBVirtualSocketImpl extends SocketImpl {
@Override
public void setOption(int optID, Object value) throws SocketException {
if(optID==SocketOptions.SO_RCVBUF) {
switch(optID) {
case SocketOptions.TCP_NODELAY:
nodelay=(boolean) value;
break;
case SocketOptions.SO_RCVBUF:
inputchachesize=(int) value;
}else if(optID==SocketOptions.SO_SNDBUF) {
break;
case SocketOptions.SO_SNDBUF:
outputchachesize=(int)value;
break;
}
}
@Override
public Object getOption(int optID) throws SocketException {
if(optID==SocketOptions.SO_BINDADDR) {
return bindaddr;
}else if(optID==SocketOptions.SO_RCVBUF) {
switch(optID) {
case SocketOptions.TCP_NODELAY:
return nodelay;
case SocketOptions.SO_RCVBUF:
return inputchachesize;
}else if(optID==SocketOptions.SO_SNDBUF) {
case SocketOptions.SO_SNDBUF:
return outputchachesize;
case SocketOptions.SO_BINDADDR:
return bindaddr;
default:
return null;
}
return null;
}
@Override
@@ -262,7 +305,6 @@ public class KLALBVirtualSocketImpl extends SocketImpl {
}
connecting = false;
if (succeed) {
} else if (refused) {
throw new ConnectException("connect refused");
} else {
@@ -329,8 +371,8 @@ public class KLALBVirtualSocketImpl extends SocketImpl {
this.acceptedSocketCloseListener = lsr;
}
private KVSIInputStream vin;
private KVSIOutputStream vout;
private InputStream vin;
private OutputStream vout;
private class KVSIInputStream extends InputStream {
private DATATPacket dtp = null;
@@ -339,9 +381,7 @@ public class KLALBVirtualSocketImpl extends SocketImpl {
private boolean shutdown=false;
@Override
public int read() throws IOException {
if(shutdown)
return -1;
if (dtp == null || (count >= dtp.getData().length && dtp.getData().length != 0)) {
if (dtp == null ) {
count = 0;
while (true) {
if (isClosed())
@@ -356,16 +396,24 @@ public class KLALBVirtualSocketImpl extends SocketImpl {
break;
}
try {
Thread.sleep(1);
synchronized (sendDeque) {
sendDeque.wait(100);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
if (dtp.getData().length == 0) {
if (dtp.getSize() == 0) {
return -1;
} else
return dtp.getData()[count++] & 0xff;
} else {
int ret= dtp.getData()[count++] & 0xff;
if(count==dtp.getSize()) {
DATATPacket.arrayRecycle.recycle(dtp.getData());
dtp=null;
}
return ret;
}
}
@Override
@@ -380,20 +428,77 @@ public class KLALBVirtualSocketImpl extends SocketImpl {
len = Math.min(len, available());
int c = read();
if (c == -1) {
return -1;
}
b[off] = (byte) c;
if (dtp == null ) {
count = 0;
while (true) {
if (isClosed())
throw new SocketException("Socket is closed");
DATATPacket dtp2 = sendDeque.poll();
if (dtp2 != null) {
dtp = dtp2;
if(countInputBytes() < inputchachesize) {
controller.sendPacketToAddress((Inet6Address) address, new ACKTPacket(dtp.getDport(), dtp.getSport(), dtp2.getNumber(),
true), 32768);
}
break;
}
try {
synchronized (sendDeque) {
sendDeque.wait(100);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
if (dtp.getSize() == 0) {
return -1;
} else {
b[off]= dtp.getData()[count++] ;
if(count==dtp.getSize()) {
DATATPacket.arrayRecycle.recycle(dtp.getData());
dtp=null;
}
}
int i = 1;
try {
for (; i < len; i++) {
c = read();
if (c == -1) {
break;
if (dtp == null ) {
count = 0;
while (true) {
if (isClosed())
throw new SocketException("Socket is closed");
DATATPacket dtp2 = sendDeque.poll();
if (dtp2 != null) {
dtp = dtp2;
if(countInputBytes() < inputchachesize) {
controller.sendPacketToAddress((Inet6Address) address, new ACKTPacket(dtp.getDport(), dtp.getSport(), dtp2.getNumber(),
true), 32768);
}
break;
}
try {
synchronized (sendDeque) {
sendDeque.wait(100);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
if (dtp.getSize() == 0) {
break;
} else {
b[off + i]= dtp.getData()[count++] ;
if(count==dtp.getSize()) {
DATATPacket.arrayRecycle.recycle(dtp.getData());
dtp=null;
}
}
b[off + i] = (byte) c;
}
} catch (IOException ee) {
}
@@ -402,40 +507,92 @@ public class KLALBVirtualSocketImpl extends SocketImpl {
@Override
public void close() throws IOException {
shutdown=true;
}
@Override
public int available() throws IOException {
AtomicInteger i = new AtomicInteger(0);
sendDeque.forEach((V) -> {
i.addAndGet(V.getData().length);
i.addAndGet(V.getSize());
});
if (dtp != null)
i.addAndGet(dtp.getData().length - count);
i.addAndGet(dtp.getSize() - count);
return i.get();
}
}
private long outputcount = 0;
private volatile long outputcount = 0;
private static final int LIMIT=65535;
private class KVSIOutputStream extends OutputStream {
private byte[] cache=new byte[65535];
private byte[] cache=DATATPacket.arrayRecycle.create();
private int count=0;
private Object lock=new Object();
@Override
public void write(int b) throws IOException {
if (isClosed())
throw new SocketException("Socket is closed");
synchronized (lock) {
cache[count++]=(byte) b;
if (count >=5773 ) {//1429?
if (count >= LIMIT) {//1429?5773?8669
flush0();
}else {
flush();
}
}
}
@Override
public void write(byte[] b, int off, int len) throws IOException {
if (isClosed())
throw new SocketException("Socket is closed");
int ol=off+len;
synchronized (lock) {
for (int i = off; i < ol; i++) {
cache[count++]=b[i];
if (count >= LIMIT) {//1429?5773?8669
flush0();
}
}
flush();
}
}
private volatile TimerTask tt;
@Override
public void flush() throws IOException {
if(nodelay) {
synchronized (lock) {
flush0();
}
}else {
if(tt==null) {
tt=new TimerTask() {
@Override
public void run() {
if(isClosed())
cancel();
try {
synchronized (lock) {
flush0();
}
} catch (IOException e) {
e.printStackTrace();
}
}
};
new Timer("粘包计时线程").scheduleAtFixedRate(tt, 0, delaytime);
}
}
}
private void flush0() throws IOException {
if (count > 0) {
try {
while (!avaliable) {
@@ -446,20 +603,18 @@ public class KLALBVirtualSocketImpl extends SocketImpl {
}
try {
while(countOutputBytes()>outputchachesize) {
Thread.sleep(1);
synchronized (sendlist) {
sendlist.wait(10);
}
}
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
byte[]ba;
if(count==cache.length) {
ba=cache;
cache=new byte[cache.length];
}else {
ba=Arrays.copyOf(cache, count);
}
SendTask x=new SendTask(controller, (Inet6Address) address, new DATATPacket(localport, port, outputcount++, ba), 5,10);
byte[] ba=cache;
cache=DATATPacket.arrayRecycle.create();
SendTask x=new SendTask(controller, (Inet6Address) address, new DATATPacket(localport, port, outputcount++, ba,count), 5,20);
x.run();
sendlist.add(x);
/*controller.sendPacketToAddress((Inet6Address) address,
@@ -470,28 +625,36 @@ public class KLALBVirtualSocketImpl extends SocketImpl {
@Override
public void close() throws IOException {
flush();
SendTask x=new SendTask(controller, (Inet6Address) address, new DATATPacket(localport, port, outputcount++, new byte[0]), 5,10);
flush0();
SendTask x=new SendTask(controller, (Inet6Address) address, new DATATPacket(localport, port, outputcount++, DATATPacket.arrayRecycle.create(),0), 5,20);
x.run();
sendlist.add(x);
/*controller.sendPacketToAddress((Inet6Address) address,
new DATATPacket(localport, port, outputcount++, new byte[0]), 5);*/
tt.cancel();
}
}
@Override
protected InputStream getInputStream() throws IOException {
public InputStream getInputStream() throws IOException {
if (vin == null) {
vin = new KVSIInputStream();
int val= vin.read();
if(val==1) {
vin=new InflaterInputStream(vin,new Inflater(true),LIMIT);
}
}
return vin;
}
@Override
protected OutputStream getOutputStream() throws IOException {
public OutputStream getOutputStream() throws IOException {
if (vout == null) {
vout = new KVSIOutputStream();
vout.write(1);
vout.flush();
vout=new DeflaterOutputStream(vout, new Deflater(Deflater.BEST_COMPRESSION, true), LIMIT, true);
}
return vout;
}
@@ -521,17 +684,23 @@ public class KLALBVirtualSocketImpl extends SocketImpl {
protected void close() throws IOException {
if (!isListening() && !isClosed()) {
closed = true;
try {
controller.sendPacketToAddress((Inet6Address) super.address, new RSTPacket(super.localport, super.port),
65537);
65537,2);
} catch (NoRouteToHostException e) {
}
if (acceptedSocketCloseListener != null)
acceptedSocketCloseListener.accept(this);
else
controller.unbind(this);
}
if (acceptedSocketCloseListener != null)
acceptedSocketCloseListener.accept(this);
else
controller.unbind(this);
sendCheckTask.cancel();
//new Exception().printStackTrace();
}
private boolean closed;
private volatile boolean closed;
private boolean isClosed() {
return closed;
@@ -8,38 +8,42 @@ import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
public class LineDecitionComparator implements Comparator<KLALBRemoteSocket> {
private Map<KLALBRemoteSocket,Long> predictedlatencys=new HashMap<>();
public LineDecitionComparator (List<KLALBRemoteSocket> krs,int priority) {
private Map<KLALBRemoteSocket,Double> predictedlatencys=new HashMap<>();
public LineDecitionComparator (List<KLALBRemoteSocket> krs,KLALBPacket curr,int priority) {
for (Iterator<KLALBRemoteSocket> iterator = krs.iterator(); iterator.hasNext();) {
KLALBRemoteSocket klalbRemoteSocket = (KLALBRemoteSocket) iterator.next();
long x=klalbRemoteSocket.getMonitor().getLatency()>>1;
x+=klalbRemoteSocket.getMonitor().getJitter()>>1;
double x=klalbRemoteSocket.getMonitor().getLatency()/2;
x+=klalbRemoteSocket.getMonitor().getJitter()/2;
AtomicLong al=new AtomicLong(0);
klalbRemoteSocket.getSendQueue().forEach((v)->{
if(v.getPriority()>=priority) {
al.addAndGet(v.getPacket().getLength());
}
});
long speed=klalbRemoteSocket.getMonitor(). getOutSpeedMax();
al.addAndGet(curr.getLength());
long speed=klalbRemoteSocket.getMonitor(). getOutSpeed();
if(speed==0) {
if(al.get()>0) {
x=Long.MAX_VALUE;
}
}else {
x+=al.get()*1000000000/speed;
x+=al.get()*1000000000.0/speed;
}
//System.out.println(x);
/*System.out.println(klalbRemoteSocket);
System.out.println(klalbRemoteSocket.getSendQueue().size());
System.out.println(x);*/
predictedlatencys.put(klalbRemoteSocket, x);
}
}
public Map<KLALBRemoteSocket, Long> getPredictedlatencys() {
public Map<KLALBRemoteSocket, Double> getPredictedlatencys() {
return predictedlatencys;
}
@Override
public int compare(KLALBRemoteSocket o1, KLALBRemoteSocket o2) {
long t1=predictedlatencys.get(o1);
long t2=predictedlatencys.get(o2);
double t1=predictedlatencys.get(o1);
double t2=predictedlatencys.get(o2);
if(t1>t2) {
return 1;
}else if(t1<t2){
@@ -49,7 +49,6 @@ public class LineManager extends Hashtable<MultipurposeSocketAddress,LineEntry>{
}
}
public synchronized void addHostPort(MultipurposeSocketAddress v) {
LineEntry le=new LineEntry(v);
if(putIfAbsent(v,le)==null)
le.open();
@@ -74,10 +73,11 @@ public class LineManager extends Hashtable<MultipurposeSocketAddress,LineEntry>{
private MultipurposeSocketAddress hp;
private KLALBRemoteSocket krs;
private volatile boolean flag=true;
private volatile boolean online=false;
private Monitor monitor=new Monitor();
public boolean isOnline() {
return online;
public Monitor getMonitor() {
return monitor;
}
public MultipurposeSocketAddress getHp() {
@@ -90,7 +90,6 @@ public class LineManager extends Hashtable<MultipurposeSocketAddress,LineEntry>{
}
public String toString() {
StringBuilder sb=new StringBuilder();
sb.append(online?"●在线 ":"○离线 ");
sb.append(hp.toString());
sb.append('\t');
sb.append(monitor.toString());
@@ -102,7 +101,6 @@ public class LineManager extends Hashtable<MultipurposeSocketAddress,LineEntry>{
sb.append(hp.toString());
sb.append('\n');
sb.append(online?"●在线\t":"○离线\t");
sb.append(monitor.toString2());
return sb.toString();
}
@@ -111,24 +109,34 @@ public class LineManager extends Hashtable<MultipurposeSocketAddress,LineEntry>{
public void run() {
while(true){
try {
krs=new KLALBRemoteSocket(hp.connectSocket(),monitor);
monitor.setState(Monitor.CONNECTING);
krs=new KLALBRemoteSocket(hp.connectSocket(3000),monitor);
//System.out.println("open");
controller.addRemoteSocket(krs);
online=true;
monitor.resetCoolingTime();
monitor.setState(Monitor.ONLINE);
krs.waitforlose();
//System.out.println("close");
online=false;
} catch (UnknownHostException e) {
} catch (IOException e) {
//e.printStackTrace();
}finally {
monitor.setState(Monitor.OFFLINE);
try {
if(krs!=null)
krs.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(!flag) {
break;
}
try {
synchronized (lock) {
lock.wait(10000);
lock.wait(monitor.getCoolingTime());
}
monitor.incCoolingTime();
} catch (InterruptedException e) {
e.printStackTrace();
}
+112 -15
View File
@@ -1,9 +1,35 @@
package org.kne.cloud.network.klalb;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Consumer;
import static org.kne.cloud.network.klalb.KLALBUtils.*;
public class Monitor {
private static Timer t=new Timer("带宽测量线程",true);
private TimerTask ptt=new TimerTask() {
@Override
public void run() {
runMonitor();
}
};
protected void runMonitor() {
updateSpeed();
}
@Override
protected void finalize() throws Throwable {
ptt.cancel();
}
public Monitor() {
t.scheduleAtFixedRate(ptt, 1000, 1000);
}
private AtomicLong inTraffic=new AtomicLong();
private AtomicLong outTraffic=new AtomicLong();
@@ -19,21 +45,34 @@ public class Monitor {
private volatile long latency ;
private volatile long jitter ;
private volatile int state=0;
public static final int OFFLINE=0;
public static final int CONNECTING=1;
public static final int ONLINE=2;
private volatile long coolingTime;
{
resetCoolingTime();
}
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
public long getInSpeedMax() {
return inSpeedMax;
}
public void updateLatency(long newlatency) {
long vj=Math.abs( latency-newlatency);;
if(jitter<vj) {
jitter=vj;
}else {
long vj=Math.abs( latency-newlatency);
jitter=(9*jitter+vj)/10;
}
if(newlatency<latency) {
/* if(newlatency<latency) {
latency=newlatency;
}else {
this.latency=(latency*9+ newlatency)/10;
}
}else {*/
this.latency=(latency+ newlatency)>>1;
//}
}
public long getOutSpeedMax() {
return outSpeedMax;
@@ -67,40 +106,98 @@ public class Monitor {
return outSpeed;
}
private long updatetime=System.nanoTime();
public void updateSpeed() {
long d=System.nanoTime()-updatetime;
long i=inTraffic.get()-inTrafficOld.get();
long o=outTraffic.get()-outTrafficOld.get();
inTrafficOld.set(inTraffic.get());
outTrafficOld.set(outTraffic.get());
inSpeed= i;
outSpeed= o;
inSpeed= i*1000000000/d;
outSpeed= o*1000000000/d;
updatetime=System.nanoTime();
//System.out.println(d+" "+o+" "+i);
if(inSpeed>inSpeedMax) {
inSpeedMax=inSpeed;
}else {
inSpeedMax=(inSpeedMax*999+inSpeed)/1000;
inSpeedMax=(inSpeedMax*9999+inSpeed)/10000;
}
if(outSpeed>outSpeedMax) {
outSpeedMax=outSpeed;
}else {
outSpeedMax=(outSpeedMax*999+outSpeed)/1000;
outSpeedMax=(outSpeedMax*9999+outSpeed)/10000;
}
if(changeListener!=null) {
changeListener.accept(this);
}
}
private Consumer<Monitor>changeListener;
public Consumer<Monitor> getChangeListener() {
return changeListener;
}
public void setChangeListener(Consumer<Monitor> changeListener) {
this.changeListener = changeListener;
}
public long getLatency() {
return latency;
}
public String toString() {
StringBuilder sb=new StringBuilder();
sb.append(getDsc());
sb.append('\t');
sb.append(bytesUnit(outTraffic.get())).append("\u2191\t").append(bytesUnit(inTraffic.get())).append("\u2193\t").append(bytesUnit(outSpeed)).append("/s\u2191\t").append(bytesUnit(inSpeed)).append("/s\u2193\t").append(latency/1000000).append("ms");
return sb.toString();
}
public String toString2() {
StringBuilder sb=new StringBuilder();
sb.append(bytesUnit(outTraffic.get())).append("\t").append(bytesUnit(inTraffic.get())).append("\t").append(bytesUnit(outSpeed)).append("/s\t").append(bytesUnit(inSpeed)).append("/s\t").append(latency/1000000).append("ms").append("\t").append(jitter/1000000).append("ms");
return sb.toString();
sb.append(getDsc());
sb.append('\t');
sb.append(bytesUnit(outTraffic.get())).append("\t").append(bytesUnit(inTraffic.get())).append("\t").append(bytesUnit(outSpeed)).append("/s\t").append(bytesUnit(inSpeed)).append("/s\t").append(latency/1000000).append("ms").append("\t").append(jitter/1000000).append("ms\t");
if(state==OFFLINE) {
sb.append((coolingTime-(System.currentTimeMillis()-mls))/1000L);
sb.append('s');
}else {
sb.append('/');
}
sb.append('\n');
sb.append(bytesUnit(outSpeedMax));
sb.append('\n');
sb.append(bytesUnit(inSpeedMax));
return sb.toString();
}
private String getDsc() {
switch(state) {
case OFFLINE:
return "○离线";
case CONNECTING:
return "◐连接中";
case ONLINE:
return "●在线";
}
return null;
}
private volatile long mls;
public long getCoolingTime() {
mls=System.currentTimeMillis();
return coolingTime;
}
public void incCoolingTime() {
coolingTime<<=1;
if(coolingTime>300000) {
coolingTime=300000;
}
}
public void resetCoolingTime() {
coolingTime=10000;
}
}
@@ -17,27 +17,20 @@ public class MonitoredSocket extends FilterSocket {
private static Timer t=new Timer("带宽测量线程",true);
private Monitor monitor;
private TimerTask ptt=new TimerTask() {
@Override
public void run() {
runMonitor();
}
};
@Override
public synchronized void close() throws IOException {
super.close();
}
public MonitoredSocket(Socket socket) {
this(socket,new Monitor());
}
public MonitoredSocket(Socket socket,Monitor monitor) {
super(socket);
t.scheduleAtFixedRate(ptt, 1000, 1000);
this.monitor=monitor;
}
protected void runMonitor() {
monitor.updateSpeed();
}
@@ -56,8 +56,10 @@ public class SendTask {
public void check(int number) throws IOException {
long limit= (1<<Math.min(4,count.get()-1))*(number<2?100:1000*number)*1000000L;
long limit= (1<<(2*Math.min(4,count.get()-1)))*(number<3?200:1000*number)*1000000L;
//long limit=(1<<Math.min(4,count.get()-1)*1000L*number+1000L)*1000000L;
if(checkTime(limit))
run();
}
@@ -70,13 +72,12 @@ public class SendTask {
try {
if(count.get()==0) {
controllker.sendPacketToAddress((Inet6Address) address,
packet, priority+count.get(),1);
packet, priority+count.get(),2);
}else {
controllker.sendPacketToAddress((Inet6Address) address,
packet, priority+count.get(),2);
}
} catch (NoRouteToHostException e) {
e.printStackTrace();
}
resetTime();
count.incrementAndGet();
@@ -23,16 +23,25 @@ public static void main(String[] args) throws UnknownHostException, IOException
def.setProperty("local", "");
AutoProperties ap=new AutoProperties(new File("klalbclient.ini"),def);
KLALBController kc=new KLALBController();
KLALBRemoteSocket kr=new KLALBRemoteSocket(new MultipurposeSocketAddress(ap.getProperty("server")).connectSocket());
MultipurposeSocketAddress msa=new MultipurposeSocketAddress(ap.getProperty("server"));
KLALBRemoteSocket kr=new KLALBRemoteSocket(msa.connectSocket());
kc.addRemoteSocket(kr);
kr.close();
System.out.println("连接成功:"+ap.getProperty("server"));
kc.getLineManager().addHostPort(msa);
TCPListener tl=new TCPListener(new MultipurposeSocketAddress(ap.getProperty("local")));
tl.setCon((s)->{
KLALBVirtualSocket kvs=null;
try {
s.setTcpNoDelay(true);
kvs=new KLALBVirtualSocket(kc, kr.getRemoteVaddr(), 23333);
new SocketBridge(s, kvs).run();
kvs.setTcpNoDelay(true);
SocketBridge dsb=new SocketBridge(s, kvs);
dsb.getSab().setDelay(1);
dsb.run();
/*CompressedSocketBridge csb=new CompressedSocketBridge(s, kvs);
csb.getSab().setDelay(1);
csb.run();*/
} catch (IOException e) {
e.printStackTrace();
}finally {
@@ -56,7 +65,7 @@ public static void main(String[] args) throws UnknownHostException, IOException
String s=scn.nextLine();
switch(s) {
case "state":
System.out.println("状态\t上传流量\t下载流量\t上传速度\t下载速度\t延迟\t抖动");
System.out.println("状态\t上传流量\t下载流量\t上传速度\t下载速度\t延迟\t抖动\t下一次重试");
LineManager le=kc.getLineManager();
for (Iterator<java.util.Map.Entry<MultipurposeSocketAddress, LineEntry>> iterator = le.entrySet().iterator(); iterator.hasNext();) {
java.util.Map.Entry<MultipurposeSocketAddress, LineEntry> hostPort = iterator.next();
@@ -119,7 +119,14 @@ public class SimpleKLALBServer {
Socket s=null;
try {
s=mpsa.connectSocket();
new SocketBridge(soc, s).run();
s.setTcpNoDelay(true);
soc.setTcpNoDelay(true);
SocketBridge dsb=new SocketBridge(s, soc);
dsb.getSab().setDelay(1);
dsb.run();
/*CompressedSocketBridge csb=new CompressedSocketBridge(s, soc);
csb.getSab().setDelay(1);
csb.run();*/
} catch (UnknownHostException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
@@ -1,25 +1,35 @@
package org.kne.cloud.network.mport;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.*;
import org.kne.io.Task;
public class SocketBridge extends Task{
private Socket a;
private Socket b;
public SocketBridge(Socket a, Socket b) {
public StreamBridge getSab() {
return sab;
}
public StreamBridge getSba() {
return sba;
}
private StreamBridge sab;
private StreamBridge sba;
public SocketBridge(Socket a, Socket b) throws IOException {
super();
this.a = a;
this.b = b;
sab = new StreamBridge(getAIN(), getBOUT());
sba = new StreamBridge(getBIN(), getAOUT());
}
@Override
protected void runTask() {
try {
StreamBridge sba=new StreamBridge(a.getInputStream(), b.getOutputStream());
StreamBridge sbb=new StreamBridge(b.getInputStream(), a.getOutputStream());
sba.runAtNewThread("SocketBridge A->B thread");
sbb.runAtNewThread("SocketBridge B->A thread");
sab.runAtNewThread("SocketBridge A->B thread");
sba.runAtNewThread("SocketBridge B->A thread");
sab.waitfortask();
sba.waitfortask();
sbb.waitfortask();
} catch (Exception e) {
e.printStackTrace();
}finally {
@@ -37,5 +47,23 @@ public class SocketBridge extends Task{
}
}
}
public Socket getA() {
return a;
}
public Socket 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();
}
}
@@ -9,6 +9,7 @@ public class StreamBridge extends Task{
private InputStream in;
private OutputStream out;
private int blocksize=65535;
private long delay=0;
public StreamBridge(InputStream in, OutputStream out) {
super();
Objects.requireNonNull(in);
@@ -25,6 +26,11 @@ public class StreamBridge extends Task{
while ((v=in.read(b))!=-1) {
out.write(b,0,v);
out.flush();
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
// TODO 自动生成的 catch 块
@@ -51,6 +57,14 @@ public class StreamBridge extends Task{
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");
}
@@ -21,7 +21,7 @@ public class ThreadTool {
}catch(Throwable e) {
//e.printStackTrace();
if(first) {
System.out.println("请使用java19以上版本以提高性能!");
System.out.println("请使用java19以上版本并开启--enable-preview选项以提高性能!");
first=false;
}
return new Thread(r, name);
@@ -14,8 +14,8 @@ import javax.sql.rowset.RowSetMetaDataImpl;
public abstract class VirtualServerSocket extends ServerSocket {
public VirtualServerSocket(SocketImpl si) throws IOException {
super();
try {
super(si);
/*try {
Class<ServerSocket> c=ServerSocket.class;
Field con =c.getDeclaredField("impl");
con.setAccessible(true);
@@ -42,7 +42,7 @@ public abstract class VirtualServerSocket extends ServerSocket {
} catch (InvocationTargetException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}*/
}
@Override
@@ -13,8 +13,21 @@ import java.nio.channels.SocketChannel;
public abstract class VirtualSocket extends Socket {
public VirtualSocket(SocketImpl si) throws SocketException {
private VirtualSocketImpl si;
public VirtualSocket(VirtualSocketImpl si) throws SocketException {
super(si);
this.si=si;
}
@Override
public InputStream getInputStream() throws IOException {
return si.getInputStream();
}
@Override
public OutputStream getOutputStream() throws IOException {
return si.getOutputStream();
}
@@ -0,0 +1,19 @@
package org.kne.cloud.network.mport;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.SocketImpl;
public abstract class VirtualSocketImpl extends SocketImpl {
@Override
public abstract InputStream getInputStream() throws IOException ;
@Override
public abstract OutputStream getOutputStream() throws IOException;
}
@@ -0,0 +1,32 @@
package org.kne.cloud.network.nathole;
import java.io.IOException;
import java.net.BindException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketOption;
import java.net.SocketOptions;
import java.nio.channels.SocketChannel;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class NatholeTestC {
public static ExecutorService exc=Executors.newCachedThreadPool();
public static void main(String[] args) throws IOException {
for (int i1 = 1024; i1 < 65536; i1++) {
int i2=i1;
exc.execute(()->{
try {
Socket s=new Socket();
System.out.println(i2);
s.bind(new InetSocketAddress("0.0.0.0", i2));
s.connect(new InetSocketAddress("10.235.16.1", 10400), 100);
System.out.println("成功!");
System.exit(0);
} catch (IOException e) {
}
});
}
}
}
@@ -0,0 +1,36 @@
package org.kne.cloud.network.nathole;
import java.io.IOException;
import java.net.BindException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.channels.SocketChannel;
public class NatholeTestS {
public static void main(String[] args) throws IOException {
for (int i1 = 1024; i1 < 65536; i1++) {
try {
SocketChannel sc= SocketChannel.open();
sc.configureBlocking(false) ;
sc.bind(new InetSocketAddress("0.0.0.0", i1));
sc.connect(new InetSocketAddress("10.235.16.1",10300));
sc.close();
int i2=i1;
new Thread(()->{
try {
ServerSocket ssk=new ServerSocket(i2);
while(true) {
Socket s=ssk.accept();
System.out.println(s);
}
} catch (IOException e) {
e.printStackTrace();
}
} ).start();
System.out.println(i1);
}catch(BindException e) {
}
}
}
}