forked from KNEMC/KLALB
UPDATE 2.2
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user