UPDATE 2.2

This commit is contained in:
Administrator
2024-01-30 16:54:57 +08:00
parent b4fccf3a03
commit e4f4c77c19
70 changed files with 4671 additions and 1520 deletions
@@ -0,0 +1,12 @@
package org.kne.cloud.network.klalb;
import java.net.InetAddress;
import java.net.ServerSocket;
public interface BindableKLALBPacketConsumer extends KLALBPacketConsumer {
public InetAddress getRemoteInetAddress() ;
public InetAddress getLocalInetAddress() ;
public int getPort() ;
public int getLocalPort();
public void setLocalPort(int i);
}
@@ -0,0 +1,6 @@
package org.kne.cloud.network.klalb;
public class CONST {
public static String klalb="KLALB";
public static String klalbver="2.2";
}
@@ -0,0 +1,68 @@
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.SocketException;
public class DatagramKLALBPacketLink implements KLALBPacketLink {
@Override
public String toString() {
return "DatagramKLALBPacketLink [ds=" + ds + "]";
}
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);
bos.reset();
KLALBOutputStream.writeKLALBPacketToStream(dos, kp);
byte[]bt=bos.toByteArray();
DatagramPacket dp=new DatagramPacket(bt,bt.length);
ds.send(dp);
}
private byte[]bc=new byte[65535];
@Override
public KLALBPacket readPacket() throws IOException {
DatagramPacket dp=new DatagramPacket(bc, bc.length);
ds.receive(dp);
DataInputStream dis=new DataInputStream(new ByteArrayInputStream(bc, 0, dp.getLength()));
KLALBPacket kp=KLALBInputStream.readKLALBPacketFromStream(dis);
dis.close();
//System.out.println(" RX:"+kp);
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();
}
}
@@ -0,0 +1,7 @@
package org.kne.cloud.network.klalb;
import java.util.function.BiConsumer;
public interface KLALBPacketConsumer extends BiConsumer<KLALBRemoteLine, KLALBPacket> {
}
@@ -0,0 +1,13 @@
package org.kne.cloud.network.klalb;
import java.io.IOException;
import java.net.SocketException;
public interface KLALBPacketLink {
public void writePacket(KLALBPacket kp) 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;
}
@@ -0,0 +1,97 @@
package org.kne.cloud.network.klalb;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.function.Consumer;
import org.kne.cloud.network.KLALBDetectorItem;
import org.kne.cloud.network.MultipurposeSocketAddress;
import org.kne.cloud.network.ProtocolDetector;
import org.kne.cloud.network.ProtocolDetectorServerSocket;
import org.kne.cloud.network.ProtocolDetectorSocket;
import org.kne.cloud.network.SocketListener;
public class KLALBProtocolDetectSocketListener extends SocketListener {
private volatile Consumer<Socket> conx;
private KLALBController klalbController;
@Override
protected void open() throws UnknownHostException, IOException {
if(serverSocket==null)
serverSocket=getMultipurposeSocketAddress().listenServerSocket();
if(!(serverSocket instanceof ProtocolDetectorServerSocket)) {
ProtocolDetector pd=new ProtocolDetector();
pd.add(new KLALBDetectorItem());
serverSocket=new ProtocolDetectorServerSocket(serverSocket,pd);
}
super.open();
}
public KLALBProtocolDetectSocketListener(MultipurposeSocketAddress multipurposeSocketAddress,KLALBController klalbc) throws IOException {
super(multipurposeSocketAddress);
this.klalbController=klalbc;
}
public KLALBProtocolDetectSocketListener(ServerSocket tserverSocket,KLALBController klalbc) throws IOException {
super(tserverSocket);
this.klalbController=klalbc;
}
{
super.setCon((soc)->{
ProtocolDetectorSocket pds=(ProtocolDetectorSocket) soc;
if(!pds.getProtocolStack().isEmpty()&&pds.getProtocolStack().pop().getName().equals("KLALB")) {
KLALBRemoteLine krs=null;
try {
krs = new KLALBRemoteLine(new StreamKLALBPacketLink(pds));
klalbController.addRemoteLine(krs);
} catch (Exception e) {
e.printStackTrace();
try {
soc.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}else {
if(conx!=null) {
try {
conx.accept(soc);
} catch (Exception e) {
e.printStackTrace();
try {
soc.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}else {
try {
soc.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
});
}
@Override
public Consumer<Socket> getCon() {
return conx;
}
@Override
public void setCon(Consumer<Socket> conx) {
this.conx=conx;
}
public KLALBController getKlalbController() {
return klalbController;
}
}
@@ -0,0 +1,502 @@
package org.kne.cloud.network.klalb;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.net.BindException;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
import java.util.Vector;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.LockSupport;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Supplier;
import org.kne.cloud.network.MultipurposeSocketAddress;
import org.kne.cloud.network.ThreadTool;
public class KLALBRemoteLine implements Comparable<KLALBRemoteLine>{
private volatile boolean closed=false;
private volatile Supplier<Inet6Address> localVaddrSupplier;
public Supplier<Inet6Address> getLocalVaddrSupplier() {
return localVaddrSupplier;
}
public void setLocalVaddrSupplier(Supplier<Inet6Address> localVaddrSupplier) {
this.localVaddrSupplier = localVaddrSupplier;
}
private volatile Inet6Address remoteVaddr;
public Inet6Address getRemoteVaddr() throws SocketTimeoutException {
return remoteVaddr;
}
public void waitForRemoteVaddrAvaliable(long timeout) throws SocketTimeoutException {
long s=System.nanoTime();
while(remoteVaddr==null) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(System.nanoTime()-s>timeout*1000000)
throw new SocketTimeoutException();
}
}
public Monitor getMonitor() {
return monitor;
}
public String toString() {
return remoteVaddr+"\t"+monitor.toString()+"\t"+sumNextPacketCount();
}
public String toString2() {
return remoteVaddr+"\t"+monitor.toString2();
}
private Monitor monitor;
private volatile KLALBPacketLink kplink;
private MultipurposeSocketAddress bindAddress;
private MultipurposeSocketAddress socketAddress;
private Thread lthd;
public void setKplink(KLALBPacketLink kplink) {
this.kplink = kplink;
}
public KLALBPacketLink getKplink() {
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());
}
}
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, MultipurposeSocketAddress bindaddr) {
this(mpa,bindaddr,new Monitor());
}
PrintStream pw;
private void startRecord() {
try {
pw=new PrintStream(UUID.randomUUID()+".csv");
pw.println("时间,状态,上传速度,下载速度,上传延迟,下载延迟,往返延迟,抖动");
ThreadTool.makePDaemonThreadIfSupport("BigData Record", ()->{
while(true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
pw.println(System.currentTimeMillis()+","+monitor.getState()+","+monitor.getOutSpeedAvg()+","+monitor.getInSpeedAvg()+","+sndDelayFactor+","+rcvDelayFactor+","+monitor.getLatencyAvg()+","+monitor.getJitter());
}
}).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("远程发送线程", () -> {
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);
}
}
Thread.yield();
}
} catch (IOException e) {
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;
if(readTime>stime) {
stime=readTime;
}else {
stime=(stime*99+readTime)/100;
}
if(stime<3000000000L) {
stime=3000000000L;
}
//System.out.println(readTime);
kplink.setSoTimeout((int) (stime/1000000));
if(kpp==null)
break;
switch (kpp.getType()) {
case KLALBPacket.PING:
sendPacket(new PONGPacket(((PINGPacket) kpp).getTime(),kpp.getRcvtime(),System.nanoTime()), -1);
break;
case KLALBPacket.PONG:
PONGPacket png=(PONGPacket) kpp;
long ul=png.getRcvtime()-( png.getTimepingsnd()+(png.getTimepongsnd()-png.getTimepingrcv()));
//System.out.println(toString()+"\t"+ul);
monitor.updateLatency (ul);
long DsndDelayFactor=png.getTimepingrcv()- png.getTimepingsnd();
long DrcvDelayFactor=png.getRcvtime()- png.getTimepongsnd();
//sndDelayFactor=DsndDelayFactor;
//rcvDelayFactor=DrcvDelayFactor;
if(sndDelayFactor==Long.MIN_VALUE) {
sndDelayFactor=DsndDelayFactor;
}else {
sndDelayFactor=(sndDelayFactor+ DsndDelayFactor)/2;
}
if(rcvDelayFactor==Long.MIN_VALUE) {
rcvDelayFactor=DrcvDelayFactor;
}else {
rcvDelayFactor=(rcvDelayFactor+ DrcvDelayFactor)/2;
}
LockSupport.unpark(tlock);
break;
case KLALBPacket.VADDRREQ:
sendPacket(new VADDRPacket(localVaddrSupplier.get()), -1);
break;
case KLALBPacket.VADDR:
remoteVaddr=((VADDRPacket) kpp).getVaddr();
sendPacket(new VADDRACKPacket(), -1);
break;
case KLALBPacket.VADDRACK:
if(fst) {
monitor.resetCoolingTime();
monitor.setState(Monitor.ONLINE);
fst=false;
}
break;
case KLALBPacket.TEST:
break;
default:
while(rec==null) {
Thread.sleep(1);
}
rec.accept(KLALBRemoteLine.this,kpp);
break;
}
Thread.yield();
}
} catch (IOException e) {
e.printStackTrace();
} 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(monitor.getCoolingTime()*1000000L);
monitor.incCoolingTime();
}
endRecord();
}).start();
}
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());
return packet;
}
private void writePacketToKPL(KLALBPacket packet) throws IOException {
monitor.getOutTrafficAL().addAndGet(packet.getLength());
kplink.writePacket(packet);
/*if(!(packet instanceof PINGPacket) )
if(!(packet instanceof PONGPacket) )
System.err.println("TX:" + packet);*/
}
public void close() {
closed=true;
try {
if(kplink!=null)
kplink.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public boolean isClosed() {
return closed;
}
private volatile long time = System.nanoTime();
private volatile long pingInterval=1000000000L;
private boolean checkPingTime() {
long cu = System.nanoTime();
if (cu - time > pingInterval) {
time = cu;
return true;
} else {
return false;
}
}
private volatile BiConsumer<KLALBRemoteLine, KLALBPacket> rec;
//private Object lock=new Object();
private volatile Thread tlock;
private List<SumQueue<KLALBPacket>> sendDequeList =new ArrayList<SumQueue<KLALBPacket>>();
{
for(int i=0;i<12;i++) {
sendDequeList.add(new SumQueue<KLALBPacket>(new ConcurrentLinkedQueue<>()));
}
}
private KLALBPacket getNextPacket() {
for (Iterator<SumQueue<KLALBPacket>> iterator = sendDequeList.iterator(); iterator.hasNext();) {
SumQueue<KLALBPacket> queue = (SumQueue<KLALBPacket>) 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<SumQueue<KLALBPacket>> iterator = sendDequeList.iterator(); iterator.hasNext();) {
SumQueue<KLALBPacket> queue = (SumQueue<KLALBPacket>) iterator.next();
i+=queue.getSumValue();
}
return i;
}
private long sumNextPacketCount() {
long i=0;
for (Iterator<SumQueue<KLALBPacket>> iterator = sendDequeList.iterator(); iterator.hasNext();) {
SumQueue<KLALBPacket> queue = (SumQueue<KLALBPacket>) iterator.next();
i+=queue.size();
}
return i;
}
public void sendPacket(KLALBPacket kp) {
sendPacket(kp, 5);
}
public void sendPacket(KLALBPacket blk,int prio) {
sendDequeList.get(prio+1).add(blk);
LockSupport.unpark(tlock);
}
public void setPacketReceiver(BiConsumer<KLALBRemoteLine,KLALBPacket> rec) {
this.rec = rec;
}
public void remoeFromSendQueue(KLALBPacket klalbPacket) {
for (Iterator<SumQueue<KLALBPacket>> iterator = sendDequeList.iterator(); iterator.hasNext();) {
SumQueue<KLALBPacket> queue = iterator.next();
queue.removeIf((x)->{
return x.equals(klalbPacket);
});
}
}
public long statLengthBefore(int priority) {
AtomicLong al=new AtomicLong();
int n=0;
for (Iterator<SumQueue<KLALBPacket>> iterator = sendDequeList.iterator(); iterator.hasNext();n++) {
if(n>priority) {
break;
}
SumQueue<KLALBPacket> queue = iterator.next();
al.addAndGet(queue.getSumValue());
}
return al.get();
}
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;
}
}
@Override
public int compareTo(KLALBRemoteLine o2) {
long t1=this.predictTime;
long t2=o2.predictTime;
if(t1>t2) {
return 1;
}else if(t1<t2){
return -1;
}else {
return 0;
}
}
public void reconnectImmediately() {
if(lthd!=null) {
LockSupport.unpark(lthd);
}
}
}
@@ -1,267 +0,0 @@
package org.kne.cloud.network.klalb;
import java.io.IOException;
import java.net.Inet6Address;
import java.net.NoRouteToHostException;
import java.net.Socket;
import java.net.SocketException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Consumer;
import org.kne.cloud.network.mport.ThreadTool;
public class KLALBRemoteSocket extends MonitoredSocket {
private Inet6Address remoteVaddr;
private KLALBController controller;
public KLALBController getController() {
return controller;
}
protected void setController(KLALBController controller) {
this.controller = controller;
}
public Inet6Address getRemoteVaddr() {
return remoteVaddr;
}
public String toString() {
return super.toString()+ getMonitor().toString();
}
public KLALBRemoteSocket(Socket socket) {
this(socket,new Monitor());
}
public KLALBRemoteSocket(Socket socket,Monitor m) {
super(socket,m);
try {
//socket.setSendBufferSize(32768);
//socket.setReceiveBufferSize(65535);
//System.out.println(socket.getSendBufferSize()+" "+socket.getReceiveBufferSize());
socket.setTcpNoDelay(true);
socket.setSoTimeout(10000);
} catch (SocketException e1) {
e1.printStackTrace();
}
ThreadTool.makeVDaemonThreadIfSupport("远程接收线程", () -> {
try {
while (!isClosed()) {
KLALBPacket kpp = getInputStream().readPacket();
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(600);
} catch (SocketException e1) {
// TODO 自动生成的 catch 块
e1.printStackTrace();
}
}else {
System.out.println("RX:" + kpp);
if(kpp instanceof VADDRPacket) {
remoteVaddr=((VADDRPacket) kpp).getVaddr();
}
while(rec==null) {
Thread.sleep(1);
}
rec.accept(kpp);
}
}
} catch (IOException e) {
//e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
try {
close();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
ThreadTool.makeVDaemonThreadIfSupport("远程发送线程", () -> {
try {
while (!isClosed()) {
if(checkPingTime()) {
getOutputStream().writePacket(new PINGPacket(System.nanoTime()));
}else {
PQItem pqi=sendQueue.poll();
if(pqi!=null) {
KLALBPacket kpp=pqi.getPacket();
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 {
synchronized (sendQueue) {
sendQueue.wait(10);
}
//Thread.sleep(1);
}
}
}
} catch (IOException e) {
// e.printStackTrace();
} catch (InterruptedException e) {
} finally {
try {
close();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
private volatile long time = System.nanoTime();
private volatile long pingInterval=500000000L;
public long getPingInterval() {
return pingInterval;
}
public void setPingInterval(long ns) {
this.pingInterval = ns;
}
private boolean checkPingTime() {
long cu = System.nanoTime();
if (cu - time > pingInterval) {
time = cu;
return true;
} else {
return false;
}
}
private KLALBInputStream kis;
private KLALBOutputStream kos;
@Override
public KLALBInputStream getInputStream() throws IOException {
if (kis == null)
kis = new KLALBInputStream(super.getInputStream());
return kis;
}
@Override
public KLALBOutputStream getOutputStream() throws IOException {
if (kos == null)
kos = new KLALBOutputStream(super.getOutputStream());
return kos;
}
private volatile Consumer<KLALBPacket> rec;
private Consumer<KLALBRemoteSocket> clo;
private PriorityBlockingQueue<PQItem> sendQueue=new PriorityBlockingQueue<PQItem>();
protected PriorityBlockingQueue<PQItem> getSendQueue() {
return sendQueue;
}
public void sendPacket(KLALBPacket kp) {
sendPacket(kp, 5);
}
public void sendPacket(KLALBPacket kp,int priority) {
sendQueue.add(new PQItem(kp, priority));
synchronized (sendQueue) {
sendQueue.notifyAll();
}
}
public void setPacketReceiver(Consumer<KLALBPacket> rec) {
this.rec = rec;
}
public void setCloseListener(Consumer<KLALBRemoteSocket> clo) {
this.clo = clo;
}
@Override
public synchronized void close() throws IOException {
if(!isClosed()&&clo!=null)
clo.accept(this);
cdl.countDown();
super.close();
sendQueue.forEach((x)->{
try {
//System.out.println("断线重发");
controller.sendPacketToAddress(remoteVaddr, x.getPacket(), x.getPriority()+1);
} catch (NoRouteToHostException e) {
}
});
}
@Override
public boolean isClosed() {
return cdl.getCount()<=0;
}
private AtomicLong al=new AtomicLong(0);
protected class PQItem implements Comparable<PQItem>{
private KLALBPacket packet;
private long index=al.getAndIncrement();
private int priority=5;
private long addtime=System.nanoTime();
public long getAddtime() {
return addtime;
}
public PQItem(KLALBPacket value, int priority) {
super();
this.packet = value;
this.priority = priority;
}
public KLALBPacket getPacket() {
return packet;
}
public long getIndex() {
return index;
}
public int getPriority() {
return priority;
}
@Override
public int compareTo(PQItem o) {
if(priority<o.priority) {
return 1;
}else if(priority>o.priority) {
return -1;
}else {
if(index>o.index) {
return 1;
}else if(index<o.index){
return -1;
}else {
return 0;
}
}
}
}
private CountDownLatch cdl=new CountDownLatch(1);
public void waitforlose() {
try {
cdl.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void remoeFromSendQueue(KLALBPacket klalbPacket) {
sendQueue.removeIf((x)->{
return x.getPacket().equals(klalbPacket);
});
}
}
@@ -0,0 +1,201 @@
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.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
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;
private TimerTask tsk;
private SystemTray st;
private TrayIcon ti;
public KLALBStateGUI(KLALBController kc,String title) throws IOException {
setResizable(false);
try {
bi = ImageIO.read(KLALBStateGUI.class.getResourceAsStream("/assets/KNEL.png"));
} catch (IOException e) {
e.printStackTrace();
}
if(bi!=null)
setIconImage(bi);
setTitleColor(new Color(0,0,0,80));
getContentPane().setBackground(new Color(0,0,0,80));
getTitlelabel().setForeground(Color.WHITE);
YScrollPane ysp = new YScrollPane(660);
ysp.setOpaque(false);
getContentPane().add(ysp);
JPanel wv = ysp.getView();
/*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(680, 430);
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();
/*progressBar.setIndeterminate(false);
progressBar.setValue(100);
progressBar.setForeground(Color.GREEN);*/
Timer t= new Timer("状态刷新线程",true);
tsk=new TimerTask() {
@Override
public void run() {
synchronized (kc.getLines()) {
loop:for (Iterator<KLALBRemoteLine> iterator = kc.getLines().iterator(); iterator.hasNext();) {
KLALBRemoteLine ent = iterator.next();
Component[] count=ysp.getView().getComponents();
for (int i = 0; i < count.length; i++) {
Component tp=count[i];
if(tp instanceof TPanel) {
if(((TPanel) tp).getTunnel().equals(ent)) {
continue loop;
}
}
}
TPanel tp=new TPanel(ent);
ysp.getView().add(tp);
}
Component[] count=ysp.getView().getComponents();
for (int i = 0; i < count.length; i++) {
Component tp=count[i];
if(tp instanceof TPanel) {
if(kc.getLines().contains(((TPanel) tp).getTunnel())) {
((TPanel) tp).updateTraffic();
}else {
ysp.getView().remove(tp);
}
}
}
}
repaint();
}
};
t.schedule(tsk, 500, 500);
}
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")
KLALBStateGUI kcg=new KLALBStateGUI(new KLALBController(),"KNE云网络负载均衡客户端 V2.0");
Thread.sleep(10000);
kcg.close();
}
}
@@ -1,162 +0,0 @@
package org.kne.cloud.network.klalb;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.Iterator;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Hashtable;
import org.kne.cloud.network.klalb.LineManager.LineEntry;
import org.kne.cloud.network.mport.MultipurposeSocketAddress;
import org.kne.cloud.network.mport.ThreadTool;
public class LineManager extends Hashtable<MultipurposeSocketAddress,LineEntry>{
private Object lock=new Object();
private KLALBController controller;
public LineManager(KLALBController controller) {
super();
this.controller = controller;
}
/*public void applyList(HostPortList hpl) {
HostPortList lh=(HostPortList) hpl.clone();
for (Iterator<LineEntry> iterator = hm.iterator(); iterator.hasNext();) {
LineEntry hostPort = (LineEntry) iterator.next();
lh.remove(hostPort.getHp());
}
for (Iterator iterator = lh.iterator(); iterator.hasNext();) {
MultipurposeSocketAddress hostPort = (MultipurposeSocketAddress) iterator.next();
LineEntry le=new LineEntry(hostPort);
hm.add(le);
ThreadTool.makeVDaemonThreadIfSupport("线路监视线程", le).start();
}
for (Iterator<LineEntry> iterator = hm.iterator(); iterator.hasNext();) {
LineEntry hostPort = (LineEntry) iterator.next();
if(!hpl.contains(hostPort.getHp())) {
hostPort.close();
iterator.remove();
}
}
}*/
public void retry() {
synchronized (lock) {
lock.notifyAll();
}
}
public synchronized void addHostPort(MultipurposeSocketAddress v) {
LineEntry le=new LineEntry(v);
if(putIfAbsent(v,le)==null)
le.open();
}
public synchronized void removeHostPort(MultipurposeSocketAddress v) {
for (Iterator<java.util.Map.Entry<MultipurposeSocketAddress, LineEntry>> iterator = entrySet().iterator(); iterator.hasNext();) {
java.util.Map.Entry<MultipurposeSocketAddress, LineEntry> hostPort = iterator.next();
if(hostPort.getValue().equals(v)) {
hostPort.getValue().close();
iterator.remove();
}
}
}
public KLALBController getController() {
return controller;
}
public class LineEntry implements Runnable{
private MultipurposeSocketAddress hp;
private KLALBRemoteSocket krs;
private volatile boolean flag=true;
private Monitor monitor=new Monitor();
public Monitor getMonitor() {
return monitor;
}
public MultipurposeSocketAddress getHp() {
return hp;
}
public LineEntry(MultipurposeSocketAddress hp) {
super();
this.hp = hp;
}
public String toString() {
StringBuilder sb=new StringBuilder();
sb.append(hp.toString());
sb.append('\t');
sb.append(monitor.toString());
return sb.toString();
}
public String toString2() {
StringBuilder sb=new StringBuilder();
sb.append(hp.toString());
sb.append('\n');
sb.append(monitor.toString2());
return sb.toString();
}
@Override
public void run() {
while(true){
try {
monitor.setState(Monitor.CONNECTING);
krs=new KLALBRemoteSocket(hp.connectSocket(3000),monitor);
//System.out.println("open");
controller.addRemoteSocket(krs);
monitor.resetCoolingTime();
monitor.setState(Monitor.ONLINE);
krs.waitforlose();
//System.out.println("close");
} 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(monitor.getCoolingTime());
}
monitor.incCoolingTime();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void open() {
ThreadTool.makeVDaemonThreadIfSupport("线路监视线程", this).start();
}
public void close() {
flag=false;
if(krs!=null)
try {
krs.close();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
}
@@ -0,0 +1,63 @@
package org.kne.cloud.network.klalb;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicInteger;
public class NACKTPacket extends KLALBPacket implements PortPacket{
private int sport,dport;
private long number;
public NACKTPacket(int sport,int dport,long number) {
super(NACKT);
this.sport=sport;
this.dport=dport;
this.number=number;
}
public NACKTPacket() {
super(NACKT);
}
@Override
public String toString() {
return "NACKT "+sport+"->"+dport+" "+number+"[]";
}
public int getSport() {
return sport;
}
@Override
public long getLength() {
return super.getLength()+17;
}
public int getDport() {
return dport;
}
public long getNumber() {
return number;
}
@Override
protected void writeToStream(DataOutput dto) throws IOException {
super.writeToStream(dto);
dto.writeInt(sport);
dto.writeInt(dport);
dto.writeLong(number);
}
@Override
protected void readFromStream(DataInput din) throws IOException {
super.readFromStream(din);
sport=din.readInt();
dport=din.readInt();
number=din.readLong();
}
}
@@ -0,0 +1,243 @@
package org.kne.cloud.network.klalb;
import java.net.BindException;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import com.google.gson.internal.Pair;
public class PortBinder {
private static Inet6Address ANYLA;
static {
try {
ANYLA=(Inet6Address) Inet6Address.getByAddress(new byte[16]);
} catch (UnknownHostException e) {
}
}
private KLALBController controller;
public PortBinder(KLALBController controller) {
super();
this.controller = controller;
}
private ReentrantReadWriteLock bindMaplock=new ReentrantReadWriteLock();
private Map<InetSocketAddress,BindableKLALBPacketConsumer>bindMap=new ConcurrentHashMap<>();
private ReentrantReadWriteLock listenMaplock=new ReentrantReadWriteLock();
private Map<InetSocketAddress,BindableKLALBPacketConsumer>listenMap=new ConcurrentHashMap<>();
private ReentrantReadWriteLock connectMaplock=new ReentrantReadWriteLock();
private Map<Pair<InetSocketAddress,InetSocketAddress>,BindableKLALBPacketConsumer>connectMap=new ConcurrentHashMap<>();
private volatile int portn=65535;
public void bind(BindableKLALBPacketConsumer ks) throws BindException {
bindMaplock.writeLock().lock();
try {
int pold=ks.getLocalPort();
if(pold==0) {
int portnod=portn+1;
if(portnod>65535) {
portnod=1;
}
int cnt=0;
while(true) {
portn++;
if(portn>65535) {
portn=1;
}
if(portn==portnod) {
cnt++;
if(cnt>1) {
throw new BindException("can't alloc port");
}
}
boolean flag=true;
for (Iterator<InetSocketAddress> iterator = bindMap.keySet().iterator(); iterator.hasNext();) {
InetSocketAddress bindableKLALBPacketConsumer = (InetSocketAddress) iterator
.next();
if(Objects.equals(ks.getLocalInetAddress(), bindableKLALBPacketConsumer.getAddress())&&portn==bindableKLALBPacketConsumer.getPort()) {
flag=false;
break;
}
}
if(flag)
break;
}
ks.setLocalPort(portn);
}else {
for (Iterator<InetSocketAddress> iterator = bindMap.keySet().iterator(); iterator.hasNext();) {
InetSocketAddress bindableKLALBPacketConsumer = (InetSocketAddress) iterator
.next();
if(Objects.equals(ks.getLocalInetAddress(), bindableKLALBPacketConsumer.getAddress())&&pold==bindableKLALBPacketConsumer.getPort()) {
throw new BindException("port " + pold + " is already bind!");
}
}
}
bindMap.put(new InetSocketAddress(ks.getLocalInetAddress(), ks.getLocalPort()),ks);
}finally {
bindMaplock.writeLock().unlock();
}
}
public void unbind(BindableKLALBPacketConsumer ks) {
bindMaplock.writeLock().lock();
try {
removeAsValue(bindMap, ks);
}finally {
bindMaplock.writeLock().unlock();
}
}
public void connect(BindableKLALBPacketConsumer ks) throws BindException {
connectMaplock.writeLock().lock();
try {
connectMap.put(new Pair<InetSocketAddress, InetSocketAddress>( new InetSocketAddress(ks.getLocalInetAddress(), ks.getLocalPort()), new InetSocketAddress(ks.getRemoteInetAddress(), ks.getPort())),ks);
}finally {
connectMaplock.writeLock().unlock();
}
}
public void disconnect(BindableKLALBPacketConsumer ks) throws BindException {
connectMaplock.writeLock().lock();
try {
removeAsValue(connectMap, ks);
}finally {
connectMaplock.writeLock().unlock();
}
}
public void listen(BindableKLALBPacketConsumer ks) throws BindException {
listenMaplock.writeLock().lock();
try {
listenMap.put(new InetSocketAddress(ks.getLocalInetAddress(), ks.getLocalPort()),ks);
}finally {
listenMaplock.writeLock().unlock();
}
}
public void unlisten(BindableKLALBPacketConsumer ks) throws BindException {
/*System.out.println(listenMap);
new RuntimeException("!").printStackTrace();*/
listenMaplock.writeLock().lock();
try {
removeAsValue(listenMap, ks);
}finally {
listenMaplock.writeLock().unlock();
}
}
private static void removeAsValue(Map m,Object obj) {
Collection col= m.values();
for (Iterator iterator = col.iterator(); iterator.hasNext();) {
Object object = (Object) iterator.next();
if(object.equals(obj)) {
iterator.remove();
}
}
}
/*private ReadWriteLock rwl=new ReentrantReadWriteLock();
private List<BindableKLALBPacketConsumer> bindlist=new ArrayList<>();
public void bind(BindableKLALBPacketConsumer ks) throws BindException {
rwl.writeLock().lock();
try {
int pold=ks.getLocalPort();
if(pold==0) {
int i=1;
while(true) {
if(i>65535) {
throw new BindException("can't alloc port");
}
boolean flag=true;
for (Iterator<BindableKLALBPacketConsumer> iterator = bindlist.iterator(); iterator.hasNext();) {
BindableKLALBPacketConsumer bindableKLALBPacketConsumer = (BindableKLALBPacketConsumer) iterator
.next();
if(Objects.equals(ks.getLocalInetAddress(), bindableKLALBPacketConsumer.getLocalInetAddress())&&i==bindableKLALBPacketConsumer.getLocalPort()&&Objects.equals( ks.getRemoteInetAddress(), bindableKLALBPacketConsumer.getRemoteInetAddress())&&(ks.getPort()==bindableKLALBPacketConsumer.getPort())) {
flag=false;
break;
}
}
if(flag)
break;
i++;
}
ks.setLocalPort(i);
}else {
for (Iterator<BindableKLALBPacketConsumer> iterator = bindlist.iterator(); iterator.hasNext();) {
BindableKLALBPacketConsumer bindableKLALBPacketConsumer = (BindableKLALBPacketConsumer) iterator
.next();
if(Objects.equals(ks.getLocalInetAddress(), bindableKLALBPacketConsumer.getLocalInetAddress())&&pold==bindableKLALBPacketConsumer.getLocalPort()&&Objects.equals( ks.getRemoteInetAddress(), bindableKLALBPacketConsumer.getRemoteInetAddress())&&(ks.getPort()==bindableKLALBPacketConsumer.getPort())) {
throw new BindException("port " + pold + " is already bind!");
}
}
}
bindlist.add(ks);
}finally {
rwl.writeLock().unlock();
}
}
public boolean distributePacketToConsumer(KLALBRemoteLine krl,PortPacket packet) throws SocketTimeoutException {
rwl.readLock().lock();
boolean b=false;
try {
for (Iterator<BindableKLALBPacketConsumer> iterator = bindlist.iterator(); iterator.hasNext();) {
BindableKLALBPacketConsumer bindableKLALBPacketConsumer = (BindableKLALBPacketConsumer) iterator.next();
if(bindableKLALBPacketConsumer.getLocalPort()==packet.getDport()&&(controller.getSelf().equals(bindableKLALBPacketConsumer.getLocalInetAddress())||ANYLA.equals(bindableKLALBPacketConsumer.getLocalInetAddress()))) {
if(bindableKLALBPacketConsumer.getRemoteInetAddress()==null||bindableKLALBPacketConsumer.getRemoteInetAddress().equals(ANYLA)) {
bindableKLALBPacketConsumer.accept(krl, (KLALBPacket) packet);
b=true;
}else {
if(bindableKLALBPacketConsumer.getPort()==packet.getSport()&&bindableKLALBPacketConsumer.getRemoteInetAddress().equals(krl.getRemoteVaddr())) {
bindableKLALBPacketConsumer.accept(krl, (KLALBPacket) packet);
b=true;
}
}
}
}
}finally {
rwl.readLock().unlock();
}
return b;
}*/
public boolean distributePacketToConsumer(KLALBRemoteLine krl,PortPacket packet) throws SocketTimeoutException {
InetSocketAddress local=new InetSocketAddress(controller.getSelf(), packet.getDport());
InetSocketAddress remote=new InetSocketAddress(krl.getRemoteVaddr(), packet.getSport());
BindableKLALBPacketConsumer bkc=connectMap.get(new Pair<InetSocketAddress, InetSocketAddress>(local, remote));
if(bkc!=null) {
bkc.accept(krl, (KLALBPacket) packet);
return true;
}
InetSocketAddress localany=new InetSocketAddress(ANYLA, packet.getDport());
bkc=connectMap.get(new Pair<InetSocketAddress, InetSocketAddress>(localany, remote));
if(bkc!=null) {
bkc.accept(krl, (KLALBPacket) packet);
return true;
}
bkc=listenMap.get(local);
if(bkc!=null) {
bkc.accept(krl, (KLALBPacket) packet);
return true;
}
bkc=listenMap.get(localany);
if(bkc!=null) {
bkc.accept(krl, (KLALBPacket) packet);
return true;
}
return false;
}
public boolean checkIsBind(KLALBVirtualSocketImpl klalbVirtualSocketImpl) {
return bindMap.containsValue(klalbVirtualSocketImpl);
}
public boolean checkIsConnect(BindableKLALBPacketConsumer kservers,InetSocketAddress isaf) throws BindException {
return connectMap.containsKey(new Pair<InetSocketAddress, InetSocketAddress>( new InetSocketAddress(kservers.getLocalInetAddress(), kservers.getLocalPort()),isaf));
}
}
@@ -0,0 +1,8 @@
package org.kne.cloud.network.klalb;
public interface PortPacket {
public int getSport();
public int getDport();
}
@@ -0,0 +1,59 @@
package org.kne.cloud.network.klalb;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.net.SocketException;
import java.nio.Buffer;
public class StreamKLALBPacketLink implements KLALBPacketLink {
@Override
public String toString() {
return "StreamKLALBPacketLink [connectSocket=" + connectSocket + "]";
}
private Socket connectSocket;
private KLALBInputStream in;
private KLALBOutputStream out;
public StreamKLALBPacketLink(Socket connectSocket) throws IOException {
this.connectSocket=connectSocket;
connectSocket.setTcpNoDelay(true);
out=new KLALBOutputStream(connectSocket.getOutputStream());
out.flush();
in=new KLALBInputStream( connectSocket.getInputStream());
//connectSocket.setSendBufferSize(1024*1024*1024);
}
@Override
public void writePacket(KLALBPacket kp) throws IOException {
out.writePacket(kp);
}
@Override
public KLALBPacket readPacket() throws IOException {
return in.readPacket();
}
@Override
public void close() throws IOException {
connectSocket.close();
}
@Override
public boolean isClosed() {
return connectSocket.isClosed();
}
@Override
public void setSoTimeout(int val) throws SocketException {
connectSocket.setSoTimeout(val);
}
@Override
public int getSoTimeout() throws SocketException {
return connectSocket.getSoTimeout();
}
}
@@ -0,0 +1,216 @@
package org.kne.cloud.network.klalb;
import java.util.AbstractQueue;
import java.util.Collection;
import java.util.Iterator;
import java.util.Queue;
import java.util.Spliterator;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Consumer;
import java.util.function.IntFunction;
import java.util.function.Predicate;
import java.util.stream.Stream;
public class SumQueue<T extends Sumable> extends AbstractQueue<T> implements Queue<T> {
private AbstractQueue<T> abq;
public SumQueue(AbstractQueue<T> abq) {
this.abq=abq;
}
private AtomicLong sumed=new AtomicLong();
public long getSumValue() {
return sumed.get();
}
private void resum() {
AtomicLong l=new AtomicLong();
forEach((t)->{
l.addAndGet(t.getValue());
});
sumed.set(l.get());
}
@Override
public boolean removeIf(Predicate<? super T> filter) {
boolean removeIf = abq.removeIf(filter);
resum();
return removeIf;
}
@Override
public boolean offer(T e) {
boolean offer = abq.offer(e);
if(offer)
sumed.addAndGet(e.getValue());
return offer;
}
@Override
public T poll() {
T poll = abq.poll();
if(poll!=null) {
sumed.addAndGet(-poll.getValue());
}
return poll;
}
@Override
public boolean add(T e) {
boolean add = abq.add(e);
if(add) {
sumed.addAndGet(e.getValue());
}
return add;
}
@Override
public T remove() {
T remove = abq.remove();
if(remove!=null) {
sumed.addAndGet(-remove.getValue());
}
return remove;
}
@Override
public void clear() {
abq.clear();
sumed.set(0);
}
@Override
public boolean addAll(Collection<? extends T> c) {
boolean addAll = abq.addAll(c);
resum();
return addAll;
}
@Override
public Iterator<T> iterator() {
return null;
}
@Override
public boolean remove(Object o) {
boolean b = abq.remove(o);
if(b)
sumed.addAndGet(((Sumable)o).getValue());
return b;
}
@Override
public boolean removeAll(Collection<?> c) {
boolean removeAll = abq.removeAll(c);
resum();
return removeAll;
}
@Override
public boolean retainAll(Collection<?> c) {
boolean retainAll = abq.retainAll(c);
resum();
return retainAll;
}
@Override
public T element() {
return (T) abq.element();
}
@Override
public T peek() {
return (T) abq.peek();
}
@Override
public int size() {
return abq.size();
}
@Override
public boolean isEmpty() {
return abq.isEmpty();
}
@Override
public boolean contains(Object o) {
return abq.contains(o);
}
@Override
public Object[] toArray() {
return abq.toArray();
}
@Override
public Spliterator<T> spliterator() {
return abq.spliterator();
}
@Override
public Stream<T> stream() {
// TODO 自动生成的方法存根
return abq.stream();
}
@Override
public Stream<T> parallelStream() {
// TODO 自动生成的方法存根
return abq.parallelStream();
}
@Override
public void forEach(Consumer<? super T> action) {
// TODO 自动生成的方法存根
abq.forEach(action);
}
@Override
public boolean containsAll(Collection<?> c) {
// TODO 自动生成的方法存根
return abq.containsAll(c);
}
@Override
public <T> T[] toArray(IntFunction<T[]> generator) {
return (T[]) abq.toArray(generator);
}
@Override
public <T> T[] toArray(T[] a) {
// TODO 自动生成的方法存根
return (T[]) abq.toArray(a);
}
@Override
public String toString() {
// TODO 自动生成的方法存根
return abq.toString();
}
}
@@ -0,0 +1,5 @@
package org.kne.cloud.network.klalb;
public interface Sumable {
public long getValue();
}
@@ -0,0 +1,37 @@
package org.kne.cloud.network.klalb;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
public class TESTPacket extends KLALBPacket {
private static byte[]K=new byte[1024];
@Override
public long getLength() {
return super.getLength()+1024;
}
public TESTPacket() {
super(TEST);
}
@Override
public String toString() {
return "TEST";
}
@Override
protected void writeToStream(DataOutput dto) throws IOException {
super.writeToStream(dto);
dto.write(K);
}
@Override
protected void readFromStream(DataInput din) throws IOException {
super.readFromStream(din);
din.readFully(K, 0, K.length);
}
}
+132
View File
@@ -0,0 +1,132 @@
package org.kne.cloud.network.klalb;
import javax.swing.JPanel;
import javax.swing.JLabel;
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.SwingConstants;
import javax.swing.border.LineBorder;
import java.awt.Font;
import java.util.Objects;
public class TPanel extends JPanel {
private JLabel tname;
private JLabel targ;
private KLALBRemoteLine tunnel;
@Override
public int hashCode() {
return Objects.hash(tunnel);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
TPanel other = (TPanel) obj;
return Objects.equals(tunnel, other.tunnel);
}
public JLabel getTname() {
return tname;
}
public JLabel getTarg() {
return targ;
}
/**
* @wbp.parser.constructor
*/
public TPanel(KLALBRemoteLine t) {
this.tunnel = t;
setOpaque(false);
setLayout(new BorderLayout(0, 0));
tname = new JLabel();
if(t.getSocketAddress()!=null) {
tname.setText(t.getSocketAddress().toString());
}else {
tname.setText(t.getKplink().toString());
}
tname.setFont(new Font("宋体", Font.BOLD, 16));
add(tname, BorderLayout.WEST);
targ = new JLabel();
targ.setFont(new Font("宋体", Font.PLAIN, 13));
targ.setHorizontalAlignment(SwingConstants.TRAILING);
targ.setForeground(Color.YELLOW);
add(targ, BorderLayout.CENTER);
setBorder(new LineBorder(Color.BLACK));
setSize(650, 25);
setPreferredSize(getSize());
}
private volatile long up, down, ups, downs;
private volatile long delay=Long.MAX_VALUE;
public long getDelay() {
return delay;
}
private void updateText() {
String dl;
if (delay == Long.MIN_VALUE)
dl = "??";
else
dl = Long.toString(delay / 1000000L);
targ.setText(bytesUnit(up) + "\u2191 " + bytesUnit(down) + "\u2193 " + bytesUnit(ups) + "/s\u2191 "
+ bytesUnit(downs) + "/s\u2193 " + dl + "ms");
}
public KLALBRemoteLine getTunnel() {
return tunnel;
}
private String bytesUnit(long v) {
if (v >= 1024L * 1024 * 1024 * 1024 * 1024) {
return String.format("%.1f", v / (1024.0 * 1024.0 * 1024.0 * 1024.0 * 1024.0)) + "PB";
} else if (v >= 1024L * 1024 * 1024 * 1024) {
return String.format("%.1f", v / (1024.0 * 1024.0 * 1024.0 * 1024.0)) + "TB";
} else if (v >= 1024L * 1024 * 1024) {
return String.format("%.1f", v / (1024.0 * 1024.0 * 1024.0)) + "GB";
} else if (v >= 1024L * 1024) {
return String.format("%.1f", v / (1024.0 * 1024.0)) + "MB";
} else if (v >= 1024L) {
return String.format("%.1f", v / (1024.0)) + "KB";
} else {
return v + "B";
}
}
public void updateTraffic() {
switch (tunnel.getMonitor().getState()) {
case Monitor.OFFLINE:
tname.setForeground(Color.RED);
break;
case Monitor.CONNECTING:
tname.setForeground(Color.YELLOW);
break;
case Monitor.ONLINE:
tname.setForeground(Color.GREEN);
break;
default:
break;
}
up = tunnel.getMonitor().getOutTraffic();
down = tunnel.getMonitor().getInTraffic();
this.ups = tunnel.getMonitor().getOutSpeed();
this.downs = tunnel.getMonitor().getInSpeed();
this.delay = tunnel.getMonitor().getLatencyAvg();
//System.out.println(delay);
updateText();
}
}
@@ -0,0 +1,14 @@
package org.kne.cloud.network.klalb;
public class VADDRACKPacket extends KLALBPacket {
public VADDRACKPacket() {
super(VADDRACK);
}
@Override
public String toString() {
return "VADDRACK";
}
}
@@ -0,0 +1,14 @@
package org.kne.cloud.network.klalb;
public class VADDRREQPacket extends KLALBPacket {
public VADDRREQPacket() {
super(VADDRREQ);
}
@Override
public String toString() {
return "VADDRREQ";
}
}