forked from KNEMC/KLALB
KLALB大更新
新负载均衡算法
This commit is contained in:
@@ -17,7 +17,7 @@ public class ACKTPacket extends KLALBPacket {
|
||||
}
|
||||
|
||||
public ACKTPacket() {
|
||||
super();
|
||||
super(ACKT);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -22,7 +22,7 @@ public class DATATPacket extends KLALBPacket {
|
||||
}
|
||||
|
||||
public DATATPacket() {
|
||||
super();
|
||||
super(DATAT);
|
||||
}
|
||||
|
||||
public int getSport() {
|
||||
|
||||
@@ -11,18 +11,24 @@ import java.net.Socket;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Scanner;
|
||||
import java.util.Set;
|
||||
import java.util.Timer;
|
||||
import java.util.UUID;
|
||||
import java.util.Vector;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.kne.cloud.network.mport.MultipurposeSocketAddress;
|
||||
import org.kne.cloud.network.mport.NetworkService;
|
||||
import org.kne.cloud.network.mport.ProxyProfileEntry;
|
||||
import org.kne.cloud.network.mport.ThreadTool;
|
||||
|
||||
import javassist.ClassPool;
|
||||
@@ -33,6 +39,29 @@ import javassist.bytecode.CodeAttribute;
|
||||
import javassist.bytecode.CodeIterator;
|
||||
|
||||
public class KLALBController {
|
||||
private LineManager lineManager;
|
||||
private Supplier<String> selflineTableSupplier=()->{return null;};
|
||||
|
||||
|
||||
|
||||
|
||||
public Supplier<String> getSelflineTableSupplier() {
|
||||
return selflineTableSupplier;
|
||||
}
|
||||
|
||||
public void setSelflineTableSupplier(Supplier<String> selflineTableSupplier) {
|
||||
this.selflineTableSupplier = selflineTableSupplier;
|
||||
}
|
||||
|
||||
public LineManager getLineManager() {
|
||||
if(lineManager==null)
|
||||
lineManager=createLineManager();
|
||||
return lineManager;
|
||||
}
|
||||
|
||||
protected LineManager createLineManager() {
|
||||
return new LineManager(this);
|
||||
}
|
||||
|
||||
private Inet6Address self;
|
||||
|
||||
@@ -70,6 +99,7 @@ public class KLALBController {
|
||||
}
|
||||
|
||||
public void addRemoteSocket(KLALBRemoteSocket krs) {
|
||||
krs.setController(this);
|
||||
CountDownLatch cdl = new CountDownLatch(1);
|
||||
krs.setPacketReceiver((rec) -> {
|
||||
try {
|
||||
@@ -139,6 +169,14 @@ public class KLALBController {
|
||||
VADDRPacket var = (VADDRPacket) rec;
|
||||
setLine(var.getVaddr(), krs);
|
||||
cdl.countDown();
|
||||
}else if(rec instanceof LINESPacket) {
|
||||
LINESPacket lpt=(LINESPacket) rec;
|
||||
String s=lpt.getLines();
|
||||
Scanner scn=new Scanner(s);
|
||||
while(scn.hasNext()) {
|
||||
String sn=scn.nextLine();
|
||||
getLineManager().addHostPort(new MultipurposeSocketAddress(sn));
|
||||
}
|
||||
}
|
||||
} catch (NoRouteToHostException e) {
|
||||
e.printStackTrace();
|
||||
@@ -146,8 +184,12 @@ public class KLALBController {
|
||||
});
|
||||
krs.setCloseListener((x) -> {
|
||||
removeLine(krs);
|
||||
cdl.countDown();
|
||||
});
|
||||
krs.sendPacket(new VADDRPacket(self), 65537);
|
||||
String selflineTable=selflineTableSupplier.get();
|
||||
if(selflineTable!=null)
|
||||
krs.sendPacket(new LINESPacket(selflineTable), 65537);
|
||||
try {
|
||||
cdl.await();
|
||||
} catch (InterruptedException e) {
|
||||
@@ -155,14 +197,14 @@ public class KLALBController {
|
||||
}
|
||||
}
|
||||
|
||||
public KLALBController() {
|
||||
this.self = KLALBUtils.uuidToIP(UUID.randomUUID());
|
||||
}
|
||||
|
||||
public KLALBController(Inet6Address self) {
|
||||
this.self = self;
|
||||
}
|
||||
|
||||
public KLALBController() {
|
||||
this.self=KLALBUtils.uuidToIP(UUID.randomUUID());
|
||||
}
|
||||
|
||||
private Map<Integer, KLALBVirtualSocketImpl> bindmap = new ConcurrentHashMap<>();
|
||||
|
||||
protected Map<Integer, KLALBVirtualSocketImpl> getBindmap() {
|
||||
@@ -225,7 +267,8 @@ public class KLALBController {
|
||||
int count0 = Math.min(count, l.size());
|
||||
List<KLALBRemoteSocket> l2 = (List<KLALBRemoteSocket>) ((ArrayList<KLALBRemoteSocket>) l).clone();
|
||||
LineDecitionComparator ldc = new LineDecitionComparator(l2, priority);
|
||||
l2.sort(ldc);
|
||||
Collections.sort(l2,ldc);
|
||||
//System.out.println(l2);
|
||||
for (Iterator<KLALBRemoteSocket> iterator = l2.iterator(); iterator.hasNext();) {
|
||||
KLALBRemoteSocket krst = (KLALBRemoteSocket) iterator.next();
|
||||
krst.sendPacket(packet, priority);
|
||||
@@ -236,7 +279,16 @@ public class KLALBController {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void removeFromSend(Inet6Address addr,KLALBPacket klalbPacket) {
|
||||
synchronized (routes) {
|
||||
List<KLALBRemoteSocket> l = routes.get(addr);
|
||||
if (l != null && !l.isEmpty()) {
|
||||
l.forEach((x)->{
|
||||
x.remoeFromSendQueue(klalbPacket);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
protected boolean checkIsBind(KLALBVirtualSocketImpl klalbVirtualSocketImpl) {
|
||||
return bindmap.containsValue(klalbVirtualSocketImpl);
|
||||
}
|
||||
@@ -245,4 +297,37 @@ private Timer t=new Timer("数据包发送计时器", true);
|
||||
return t;
|
||||
}
|
||||
|
||||
public void registerToProxyTypeAs(String proxyname) {
|
||||
MultipurposeSocketAddress.getSocketFactoryRegister().put(proxyname, new KLALBVirtualSocketFactory(this));
|
||||
MultipurposeSocketAddress.getServerSocketFactoryRegister().put(proxyname, new KLALBVirtualServerSocketFactory(this));
|
||||
ProxyProfileEntry.getRegister().put(proxyname, new KLALBNetworkService());
|
||||
}
|
||||
|
||||
private class KLALBNetworkService implements NetworkService{
|
||||
|
||||
@Override
|
||||
public void listen(MultipurposeSocketAddress msa) {
|
||||
// TODO 自动生成的方法存根
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unlisten(MultipurposeSocketAddress msc) {
|
||||
// TODO 自动生成的方法存根
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connect(MultipurposeSocketAddress msa) {
|
||||
getLineManager().addHostPort(msa);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unconnect(MultipurposeSocketAddress msc) {
|
||||
getLineManager().removeHostPort(msc);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -60,6 +60,10 @@ public class KLALBInputStream extends DataInputStream {
|
||||
klp=new VADDRPacket();
|
||||
klp.readFromStream(this);
|
||||
return klp;
|
||||
case LINES:
|
||||
klp=new LINESPacket();
|
||||
klp.readFromStream(this);
|
||||
return klp;
|
||||
}
|
||||
throw new StreamCorruptedException("unknown package type:"+type);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
package org.kne.cloud.network.klalb;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
|
||||
import org.kne.cloud.network.klalb.LineManager.LineEntry;
|
||||
import org.kne.cloud.network.mport.MultipurposeSocketAddress;
|
||||
import org.kne.cloud.network.mport.ProxyProfileAnalyser;
|
||||
import org.kne.cloud.network.mport.ProxyProfileExecutor;
|
||||
import org.kne.cloud.network.mport.TCPListener;
|
||||
|
||||
public class KLALBMain {
|
||||
public static TCPListener tcpl;
|
||||
public static ServerPropties sp;
|
||||
public static KLALBController kc;
|
||||
|
||||
public static ProxyProfileExecutor pfa;
|
||||
public static File f=new File("lines.cfg");
|
||||
public static void main(String[] args) throws IOException {
|
||||
|
||||
System.out.println("KLALB负载均衡V2.0");
|
||||
sp=new ServerPropties();
|
||||
|
||||
System.out.println("虚拟地址:"+sp.getVirtualIP().getHostAddress());
|
||||
kc=new KLALBController(sp.getVirtualIP());
|
||||
kc.registerToProxyTypeAs("KLALB");
|
||||
|
||||
|
||||
|
||||
|
||||
pfa=new ProxyProfileExecutor();
|
||||
pfa.load(f);
|
||||
|
||||
Scanner scn=new Scanner(System.in);
|
||||
while(true) {
|
||||
String s=scn.next();
|
||||
String[]sc=s.split(" ");
|
||||
switch(sc[0]) {
|
||||
case "help":
|
||||
System.out.print("state:查看线路状态");
|
||||
System.out.println("reload:重新加载线路配置");
|
||||
break;
|
||||
case "reloadlines":
|
||||
pfa.load(f);
|
||||
System.out.println("重新加载线路配置成功");
|
||||
break;
|
||||
case "state":
|
||||
LineManager le=kc.getLineManager();
|
||||
for (Iterator<java.util.Map.Entry<MultipurposeSocketAddress, LineEntry>> iterator = le.entrySet().iterator(); iterator.hasNext();) {
|
||||
java.util.Map.Entry<MultipurposeSocketAddress, LineEntry> hostPort = iterator.next();
|
||||
System.out.println(hostPort.getValue() .toString());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
System.out.println("未知命令,请输入help以查询指令说明");
|
||||
}
|
||||
}
|
||||
}
|
||||
private static void openPort(int port) throws IOException {
|
||||
if(tcpl!=null)
|
||||
tcpl.close();
|
||||
tcpl=new TCPListener(new MultipurposeSocketAddress("0.0.0.0", port));
|
||||
tcpl.setCon((soc)->{
|
||||
KLALBRemoteSocket krs=new KLALBRemoteSocket(soc);
|
||||
kc.addRemoteSocket(krs);
|
||||
});
|
||||
tcpl.open();
|
||||
}
|
||||
}
|
||||
@@ -17,12 +17,9 @@ public abstract class KLALBPacket{
|
||||
public static final int ACKT=6;
|
||||
public static final int DATAU=7;
|
||||
public static final int VADDR=8;
|
||||
|
||||
public static final int LINES=9;
|
||||
private int type;
|
||||
|
||||
public KLALBPacket() {
|
||||
super();
|
||||
}
|
||||
public KLALBPacket(int type) {
|
||||
super();
|
||||
this.type = type;
|
||||
@@ -41,6 +38,7 @@ public abstract class KLALBPacket{
|
||||
|
||||
}
|
||||
public long getLength() {
|
||||
return 4;
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,7 +2,10 @@ 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;
|
||||
@@ -12,12 +15,35 @@ 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 KLALBRemoteSocket(Socket socket) {
|
||||
super(socket);
|
||||
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) {
|
||||
// TODO 自动生成的 catch 块
|
||||
e1.printStackTrace();
|
||||
}
|
||||
ThreadTool.makeVDaemonThreadIfSupport("远程接收线程", () -> {
|
||||
try {
|
||||
|
||||
@@ -25,11 +51,18 @@ public class KLALBRemoteSocket extends MonitoredSocket {
|
||||
KLALBPacket kpp = getInputStream().readPacket();
|
||||
//System.out.println("RX:" + kpp);
|
||||
if(kpp instanceof PINGPacket) {
|
||||
sendPacket(new PONGPacket(), 65540);
|
||||
sendPacket(new PONGPacket(((PINGPacket) kpp).getTime()), 65540);
|
||||
}else if(kpp instanceof PONGPacket) {
|
||||
latency.set(System.nanoTime()-pingstarttime);
|
||||
pinging=false;
|
||||
PONGPacket png=(PONGPacket) kpp;
|
||||
getMonitor().updateLatency (System.nanoTime()- png.getTime());
|
||||
try {
|
||||
socket.setSoTimeout(1100);
|
||||
} catch (SocketException e1) {
|
||||
// TODO 自动生成的 catch 块
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}else {
|
||||
|
||||
if(kpp instanceof VADDRPacket) {
|
||||
remoteVaddr=((VADDRPacket) kpp).getVaddr();
|
||||
}
|
||||
@@ -40,7 +73,7 @@ public class KLALBRemoteSocket extends MonitoredSocket {
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
//e.printStackTrace();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
@@ -55,18 +88,18 @@ public class KLALBRemoteSocket extends MonitoredSocket {
|
||||
try {
|
||||
|
||||
while (!isClosed()) {
|
||||
if(System.nanoTime()-pingstarttime>100000000000L) {
|
||||
pinging=false;
|
||||
}
|
||||
if(checkPingTime()&&!pinging) {
|
||||
getOutputStream().writePacket(new PINGPacket());
|
||||
pinging =true;
|
||||
pingstarttime=System.nanoTime();
|
||||
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);
|
||||
}else {
|
||||
Thread.sleep(1);
|
||||
@@ -74,7 +107,7 @@ public class KLALBRemoteSocket extends MonitoredSocket {
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
// e.printStackTrace();
|
||||
} catch (InterruptedException e) {
|
||||
} finally {
|
||||
try {
|
||||
@@ -87,11 +120,9 @@ public class KLALBRemoteSocket extends MonitoredSocket {
|
||||
|
||||
}
|
||||
|
||||
private volatile long pingstarttime=System.nanoTime();
|
||||
|
||||
private volatile boolean pinging=false;
|
||||
private volatile long time = System.nanoTime();
|
||||
private volatile long pingInterval=1000000000L;
|
||||
private volatile long pingInterval=500000000L;
|
||||
|
||||
public long getPingInterval() {
|
||||
return pingInterval;
|
||||
@@ -112,11 +143,8 @@ public class KLALBRemoteSocket extends MonitoredSocket {
|
||||
}
|
||||
|
||||
|
||||
private volatile boolean waitingforPing = false;
|
||||
|
||||
public long getLatency() {
|
||||
return latency.get();
|
||||
}
|
||||
|
||||
|
||||
private KLALBInputStream kis;
|
||||
private KLALBOutputStream kos;
|
||||
@@ -135,7 +163,7 @@ public class KLALBRemoteSocket extends MonitoredSocket {
|
||||
return kos;
|
||||
}
|
||||
|
||||
private AtomicLong latency = new AtomicLong();
|
||||
|
||||
private volatile Consumer<KLALBPacket> rec;
|
||||
private Consumer<KLALBRemoteSocket> clo;
|
||||
private PriorityBlockingQueue<PQItem> sendQueue=new PriorityBlockingQueue<PQItem>();
|
||||
@@ -160,9 +188,22 @@ public class KLALBRemoteSocket extends MonitoredSocket {
|
||||
}
|
||||
@Override
|
||||
public synchronized void close() throws IOException {
|
||||
super.close();
|
||||
if(!isClosed()&&clo!=null)
|
||||
clo.accept(this);
|
||||
cdl.countDown();
|
||||
super.close();
|
||||
sendQueue.forEach((x)->{
|
||||
try {
|
||||
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);
|
||||
@@ -170,6 +211,10 @@ public class KLALBRemoteSocket extends MonitoredSocket {
|
||||
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;
|
||||
@@ -201,4 +246,17 @@ public class KLALBRemoteSocket extends MonitoredSocket {
|
||||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
package org.kne.cloud.network.klalb;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketException;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import org.kne.cloud.network.mport.SocketBridge;
|
||||
import org.kne.cloud.network.mport.TCPListener;
|
||||
|
||||
public class KLALBTest1 {
|
||||
|
||||
public static void main(String[] args) throws UnknownHostException, IOException, InterruptedException {
|
||||
KLALBRemoteSocket s1=new KLALBRemoteSocket( new Socket("127.0.0.1", 8899));
|
||||
KLALBRemoteSocket s2=new KLALBRemoteSocket(new Socket("127.0.0.1", 8899));
|
||||
KLALBRemoteSocket s3=new KLALBRemoteSocket(new Socket("127.0.0.1", 8899));
|
||||
KLALBController kc=new KLALBController((Inet6Address) Inet6Address.getByName("::2"));
|
||||
kc.addRemoteSocket(s1);
|
||||
kc.addRemoteSocket(s2);
|
||||
kc.addRemoteSocket(s3);
|
||||
TCPListener tl=new TCPListener(7463);
|
||||
tl.open();
|
||||
tl.setCon((x)->{
|
||||
KLALBVirtualSocket kvs;
|
||||
try {
|
||||
kvs = new KLALBVirtualSocket(kc);
|
||||
kvs.connect(new InetSocketAddress(InetAddress.getByName("::9"), 90));
|
||||
new SocketBridge(kvs, x).run();
|
||||
} catch (SocketException e) {
|
||||
// TODO 自动生成的 catch 块
|
||||
e.printStackTrace();
|
||||
} catch (UnknownHostException e) {
|
||||
// TODO 自动生成的 catch 块
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
// TODO 自动生成的 catch 块
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
|
||||
System.out.println("c");
|
||||
Thread.sleep(20000);
|
||||
s2.close();
|
||||
while(true) {
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
package org.kne.cloud.network.klalb;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.*;
|
||||
|
||||
import org.kne.cloud.network.mport.SocketBridge;
|
||||
import org.kne.cloud.network.mport.TCPListener;
|
||||
|
||||
public class KLALBTest2 {
|
||||
public static void main(String[] args) throws IOException, InterruptedException {
|
||||
ServerSocket ssk=new ServerSocket(8899);
|
||||
KLALBRemoteSocket s1=new KLALBRemoteSocket(ssk.accept());
|
||||
KLALBRemoteSocket s2=new KLALBRemoteSocket(ssk.accept());
|
||||
KLALBRemoteSocket s3=new KLALBRemoteSocket(ssk.accept());
|
||||
KLALBController cont=new KLALBController((Inet6Address) Inet6Address.getByName("::9"));
|
||||
cont.addRemoteSocket(s1);
|
||||
cont.addRemoteSocket(s2);
|
||||
cont.addRemoteSocket(s3);
|
||||
KLALBVirtualServerSocket ksr=new KLALBVirtualServerSocket(cont);
|
||||
TCPListener tl=new TCPListener(90);
|
||||
tl.setServerSocketFactory(new KLALBVirtualServerSocketFactory(cont));
|
||||
tl.setCon((x)->{
|
||||
try {
|
||||
new SocketBridge(x, new Socket("127.0.0.1",5212)).run();
|
||||
} catch (UnknownHostException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
tl.open();
|
||||
|
||||
Thread.sleep(20000);
|
||||
s3.close();
|
||||
}
|
||||
}
|
||||
@@ -29,4 +29,29 @@ public class KLALBUtils {
|
||||
public static void main(String[] args) {
|
||||
System.out.println(uuidToIP(new UUID(-1,-1)));
|
||||
}
|
||||
public static String bytesUnit(long v) {
|
||||
if(v>=1024L*1024*1024*1024*1024) {
|
||||
return format( v/(1024.0*1024.0*1024.0*1024.0*1024.0))+"P";
|
||||
}else if(v>=1024L*1024*1024*1024) {
|
||||
return format (v/(1024.0*1024.0*1024.0*1024.0))+"T";
|
||||
}else if(v>=1024L*1024*1024) {
|
||||
return format( v/(1024.0*1024.0*1024.0))+"G";
|
||||
}else if(v>=1024L*1024) {
|
||||
return format( v/(1024.0*1024.0))+"M";
|
||||
}else if(v>=1024L) {
|
||||
return format( v/(1024.0))+"K";
|
||||
}else {
|
||||
return v+"B";
|
||||
}
|
||||
}
|
||||
private static String format( double d) {
|
||||
String fmt=String.format( "%.2f",d);
|
||||
if(fmt.length()>4) {
|
||||
fmt=fmt.substring(0, 4);
|
||||
}
|
||||
if(fmt.endsWith(".")) {
|
||||
fmt=fmt.substring(0, fmt.length()-1);
|
||||
}
|
||||
return fmt;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package org.kne.cloud.network.klalb;
|
||||
|
||||
import java.net.SocketException;
|
||||
import java.net.SocketImpl;
|
||||
import java.io.IOException;
|
||||
import java.net.*;
|
||||
|
||||
import org.kne.cloud.network.mport.VirtualSocket;
|
||||
|
||||
@@ -11,11 +11,52 @@ public class KLALBVirtualSocket extends VirtualSocket {
|
||||
|
||||
public KLALBVirtualSocket(KLALBController controler) throws SocketException {
|
||||
super(controler.createVirtualImpl());
|
||||
this.controler=controler;
|
||||
this.controler = controler;
|
||||
}
|
||||
|
||||
protected KLALBController getControler() {
|
||||
return controler;
|
||||
}
|
||||
|
||||
public KLALBVirtualSocket(KLALBController controler,String host, int port) throws UnknownHostException, IOException {
|
||||
this(controler,host != null ? new InetSocketAddress(host, port)
|
||||
: new InetSocketAddress(InetAddress.getByName(null), port), (SocketAddress) null);
|
||||
}
|
||||
|
||||
public KLALBVirtualSocket(KLALBController controler,SocketAddress address, SocketAddress localAddr) throws IOException {
|
||||
this(controler);
|
||||
// backward compatibility
|
||||
if (address == null)
|
||||
throw new NullPointerException();
|
||||
|
||||
try {
|
||||
if (localAddr != null)
|
||||
bind(localAddr);
|
||||
connect(address);
|
||||
} catch (IOException | IllegalArgumentException | SecurityException e) {
|
||||
try {
|
||||
close();
|
||||
} catch (IOException ce) {
|
||||
e.addSuppressed(ce);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public KLALBVirtualSocket(KLALBController controler,String host, int port, InetAddress localAddr, int localPort) throws IOException {
|
||||
this(controler,host != null ? new InetSocketAddress(host, port)
|
||||
: new InetSocketAddress(InetAddress.getByName(null), port),
|
||||
new InetSocketAddress(localAddr, localPort));
|
||||
}
|
||||
|
||||
public KLALBVirtualSocket(KLALBController controler,InetAddress address, int port, InetAddress localAddr, int localPort) throws IOException {
|
||||
this(controler,address != null ? new InetSocketAddress(address, port) : null,
|
||||
new InetSocketAddress(localAddr, localPort));
|
||||
}
|
||||
|
||||
public KLALBVirtualSocket(KLALBController controler,InetAddress address, int port) throws IOException {
|
||||
this(controler,address != null ? new InetSocketAddress(address, port) : null,
|
||||
(SocketAddress) null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package org.kne.cloud.network.klalb;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import javax.net.SocketFactory;
|
||||
|
||||
public class KLALBVirtualSocketFactory extends SocketFactory {
|
||||
private KLALBController controller;
|
||||
|
||||
public KLALBVirtualSocketFactory(KLALBController controller) {
|
||||
super();
|
||||
this.controller = controller;
|
||||
}
|
||||
@Override
|
||||
public Socket createSocket(String arg0, int arg1) throws IOException, UnknownHostException {
|
||||
|
||||
return new KLALBVirtualSocket(controller, arg0, arg1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket createSocket(InetAddress arg0, int arg1) throws IOException {
|
||||
return new KLALBVirtualSocket(controller, arg0, arg1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket createSocket(String arg0, int arg1, InetAddress arg2, int arg3)
|
||||
throws IOException, UnknownHostException {
|
||||
return new KLALBVirtualSocket(controller, arg0, arg1, arg2, arg3);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket createSocket(InetAddress arg0, int arg1, InetAddress arg2, int arg3) throws IOException {
|
||||
return new KLALBVirtualSocket(controller, arg0, arg1, arg2, arg3);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,14 +17,18 @@ import java.net.SocketException;
|
||||
import java.net.SocketImpl;
|
||||
import java.net.SocketOptions;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingDeque;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.LinkedBlockingDeque;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.concurrent.atomic.AtomicReferenceArray;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@@ -51,13 +55,36 @@ public class KLALBVirtualSocketImpl extends SocketImpl {
|
||||
this.outputchachesize = outputchachesize;
|
||||
}
|
||||
|
||||
private int inputchachesize = 65535 * 50;
|
||||
private int outputchachesize = 65535 * 50;
|
||||
private Inet6Address bindaddr;
|
||||
private int inputchachesize = 5773 * 100;
|
||||
private int outputchachesize = 5773 * 100;
|
||||
private Inet6Address bindaddr;{
|
||||
try {
|
||||
bindaddr=(Inet6Address) Inet6Address.getByName("::0");
|
||||
} catch (UnknownHostException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private BlockingQueue<InetSocketAddress> backlogQueue;
|
||||
private BlockingDeque<DATATPacket> sendDeque = new LinkedBlockingDeque<>();
|
||||
private Queue<DATATPacket> sendDeque = new ConcurrentLinkedQueue<>();
|
||||
private List<SendTask> sendlist=new Vector<>();
|
||||
private TimerTask sendCheckTask=new SendCheckTask();
|
||||
private class SendCheckTask extends TimerTask{
|
||||
|
||||
public void run() {
|
||||
synchronized (sendlist) {
|
||||
for (int i = 0; i < sendlist.size(); i++) {
|
||||
try {
|
||||
sendlist.get(i).check(i);
|
||||
} catch (IOException e) {
|
||||
// TODO 自动生成的 catch 块
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
private boolean succeed, refused;
|
||||
|
||||
protected boolean isListening() {
|
||||
@@ -126,16 +153,18 @@ public class KLALBVirtualSocketImpl extends SocketImpl {
|
||||
}
|
||||
}
|
||||
controller.sendPacketToAddress(from, new ACKTPacket(dtp.getDport(), dtp.getSport(), dtp.getNumber(),
|
||||
countInputBytes() < inputchachesize), 32768);
|
||||
countInputBytes() < inputchachesize), 32768,2);
|
||||
} else if (u instanceof ACKTPacket) {
|
||||
ACKTPacket ackt = (ACKTPacket) u;
|
||||
avaliable = ackt.isAvaliable();
|
||||
AtomicReference<KLALBPacket>kl=new AtomicReference<>();
|
||||
sendlist.removeIf((tsk)->{
|
||||
boolean b=tsk.getKp().getNumber()==ackt.getNumber();
|
||||
if(b)
|
||||
tsk.cancel();
|
||||
boolean b=tsk.getPacket().getNumber()==ackt.getNumber();
|
||||
if(b)
|
||||
kl.set(tsk.getPacket());
|
||||
return b;
|
||||
});
|
||||
controller.removeFromSend(from,kl.get());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
@@ -155,7 +184,7 @@ public class KLALBVirtualSocketImpl extends SocketImpl {
|
||||
private int countOutputBytes() {
|
||||
AtomicInteger i = new AtomicInteger(0);
|
||||
sendlist.forEach((c) -> {
|
||||
i.addAndGet(c.getKp().getData().length);
|
||||
i.addAndGet(c.getPacket().getData().length);
|
||||
});
|
||||
return i.get();
|
||||
}
|
||||
@@ -170,17 +199,27 @@ public class KLALBVirtualSocketImpl extends SocketImpl {
|
||||
public KLALBVirtualSocketImpl(KLALBController kc) {
|
||||
super();
|
||||
this.controller = kc;
|
||||
kc.getTimer().schedule(sendCheckTask, 50, 50);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOption(int optID, Object value) throws SocketException {
|
||||
// TODO 自动生成的方法存根
|
||||
|
||||
if(optID==SocketOptions.SO_RCVBUF) {
|
||||
inputchachesize=(int) value;
|
||||
}else if(optID==SocketOptions.SO_SNDBUF) {
|
||||
outputchachesize=(int)value;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getOption(int optID) throws SocketException {
|
||||
// TODO 自动生成的方法存根
|
||||
if(optID==SocketOptions.SO_BINDADDR) {
|
||||
return bindaddr;
|
||||
}else if(optID==SocketOptions.SO_RCVBUF) {
|
||||
return inputchachesize;
|
||||
}else if(optID==SocketOptions.SO_SNDBUF) {
|
||||
return outputchachesize;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -255,6 +294,7 @@ public class KLALBVirtualSocketImpl extends SocketImpl {
|
||||
@Override
|
||||
protected void listen(int backlog) throws IOException {
|
||||
backlogQueue = new ArrayBlockingQueue<>(backlog);
|
||||
address=bindaddr;
|
||||
}
|
||||
|
||||
private Map<InetSocketAddress, KLALBVirtualSocketImpl> accepts = new ConcurrentHashMap<>();
|
||||
@@ -268,7 +308,8 @@ public class KLALBVirtualSocketImpl extends SocketImpl {
|
||||
try {
|
||||
KLALBVirtualSocketImpl kvsi = (KLALBVirtualSocketImpl) s;
|
||||
InetSocketAddress isa = backlogQueue.take();
|
||||
|
||||
kvsi.inputchachesize=inputchachesize;
|
||||
kvsi.outputchachesize=outputchachesize;
|
||||
kvsi.port = isa.getPort();
|
||||
kvsi.address = isa.getAddress();
|
||||
kvsi.localport = localport;
|
||||
@@ -381,21 +422,21 @@ public class KLALBVirtualSocketImpl extends SocketImpl {
|
||||
|
||||
private class KVSIOutputStream extends OutputStream {
|
||||
|
||||
private ByteArrayOutputStream bos = new ByteArrayOutputStream(65535);
|
||||
|
||||
private byte[] cache=new byte[65535];
|
||||
private int count=0;
|
||||
@Override
|
||||
public void write(int b) throws IOException {
|
||||
if (isClosed())
|
||||
throw new SocketException("Socket is closed");
|
||||
bos.write(b);
|
||||
if (bos.size() >= 65535) {
|
||||
cache[count++]=(byte) b;
|
||||
if (count >=5773 ) {//1429?
|
||||
flush();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() throws IOException {
|
||||
if (bos.size() > 0) {
|
||||
if (count > 0) {
|
||||
try {
|
||||
while (!avaliable) {
|
||||
Thread.sleep(1);
|
||||
@@ -411,20 +452,27 @@ public class KLALBVirtualSocketImpl extends SocketImpl {
|
||||
// TODO 自动生成的 catch 块
|
||||
e.printStackTrace();
|
||||
}
|
||||
SendTask x=new SendTask(controller, (Inet6Address) address, new DATATPacket(localport, port, outputcount++, bos.toByteArray()), 5,5);
|
||||
x.addToTimer(1000);
|
||||
byte[]ba;
|
||||
if(count==cache.length) {
|
||||
ba=cache;
|
||||
cache=new byte[cache.length];
|
||||
}else {
|
||||
ba=Arrays.copyOf(cache, count);
|
||||
}
|
||||
SendTask x=new SendTask(controller, (Inet6Address) address, new DATATPacket(localport, port, outputcount++, ba), 5,10);
|
||||
x.run();
|
||||
sendlist.add(x);
|
||||
/*controller.sendPacketToAddress((Inet6Address) address,
|
||||
new DATATPacket(localport, port, outputcount++, bos.toByteArray()), 5);*/
|
||||
}
|
||||
bos.reset();
|
||||
count=0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
flush();
|
||||
SendTask x=new SendTask(controller, (Inet6Address) address, new DATATPacket(localport, port, outputcount++, new byte[0]), 5,5);
|
||||
x.addToTimer(1000);
|
||||
SendTask x=new SendTask(controller, (Inet6Address) address, new DATATPacket(localport, port, outputcount++, new byte[0]), 5,10);
|
||||
x.run();
|
||||
sendlist.add(x);
|
||||
/*controller.sendPacketToAddress((Inet6Address) address,
|
||||
new DATATPacket(localport, port, outputcount++, new byte[0]), 5);*/
|
||||
@@ -480,6 +528,7 @@ public class KLALBVirtualSocketImpl extends SocketImpl {
|
||||
acceptedSocketCloseListener.accept(this);
|
||||
else
|
||||
controller.unbind(this);
|
||||
sendCheckTask.cancel();
|
||||
}
|
||||
|
||||
private boolean closed;
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
package org.kne.cloud.network.klalb;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.net.Inet6Address;
|
||||
|
||||
public class LINESPacket extends KLALBPacket {
|
||||
private String lines;
|
||||
|
||||
|
||||
public String getLines() {
|
||||
return lines;
|
||||
}
|
||||
|
||||
public LINESPacket(String lines) {
|
||||
super(LINES);
|
||||
this.lines=lines;
|
||||
}
|
||||
|
||||
public LINESPacket() {
|
||||
super(LINES);
|
||||
}
|
||||
private int UTFlength(String str) {
|
||||
int strlen = str.length();
|
||||
int utflen = 0;
|
||||
for (int i = 0; i < strlen; i++) {
|
||||
int c = str.charAt(i);
|
||||
if ((c >= 0x0001) && (c <= 0x007F)) {
|
||||
utflen++;
|
||||
} else if (c > 0x07FF) {
|
||||
utflen += 3;
|
||||
} else {
|
||||
utflen += 2;
|
||||
}
|
||||
}
|
||||
return utflen;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LINES\n"+lines;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLength() {
|
||||
return super.getLength()+2+UTFlength(lines);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeToStream(DataOutput dto) throws IOException {
|
||||
super.writeToStream(dto);
|
||||
dto.writeUTF(lines);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readFromStream(DataInput din) throws IOException {
|
||||
super.readFromStream(din);
|
||||
lines=din.readUTF();
|
||||
}
|
||||
}
|
||||
@@ -12,14 +12,15 @@ public class LineDecitionComparator implements Comparator<KLALBRemoteSocket> {
|
||||
public LineDecitionComparator (List<KLALBRemoteSocket> krs,int priority) {
|
||||
for (Iterator<KLALBRemoteSocket> iterator = krs.iterator(); iterator.hasNext();) {
|
||||
KLALBRemoteSocket klalbRemoteSocket = (KLALBRemoteSocket) iterator.next();
|
||||
long x=klalbRemoteSocket.getLatency()>>1;
|
||||
long x=klalbRemoteSocket.getMonitor().getLatency()>>1;
|
||||
x+=klalbRemoteSocket.getMonitor().getJitter()>>1;
|
||||
AtomicLong al=new AtomicLong(0);
|
||||
klalbRemoteSocket.getSendQueue().forEach((v)->{
|
||||
if(v.getPriority()>=priority) {
|
||||
al.addAndGet(v.getPacket().getLength());
|
||||
}
|
||||
});
|
||||
long speed=klalbRemoteSocket.getOutSpeed();
|
||||
long speed=klalbRemoteSocket.getMonitor(). getOutSpeedMax();
|
||||
if(speed==0) {
|
||||
if(al.get()>0) {
|
||||
x=Long.MAX_VALUE;
|
||||
@@ -27,6 +28,7 @@ public class LineDecitionComparator implements Comparator<KLALBRemoteSocket> {
|
||||
}else {
|
||||
x+=al.get()*1000000000/speed;
|
||||
}
|
||||
//System.out.println(x);
|
||||
predictedlatencys.put(klalbRemoteSocket, x);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
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 volatile boolean online=false;
|
||||
private Monitor monitor=new Monitor();
|
||||
public boolean isOnline() {
|
||||
return online;
|
||||
}
|
||||
|
||||
public MultipurposeSocketAddress getHp() {
|
||||
return hp;
|
||||
}
|
||||
|
||||
public LineEntry(MultipurposeSocketAddress hp) {
|
||||
super();
|
||||
this.hp = hp;
|
||||
}
|
||||
public String toString() {
|
||||
StringBuilder sb=new StringBuilder();
|
||||
sb.append(online?"●在线 ":"○离线 ");
|
||||
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(online?"●在线\t":"○离线\t");
|
||||
sb.append(monitor.toString2());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while(true){
|
||||
try {
|
||||
krs=new KLALBRemoteSocket(hp.connectSocket(),monitor);
|
||||
//System.out.println("open");
|
||||
controller.addRemoteSocket(krs);
|
||||
online=true;
|
||||
krs.waitforlose();
|
||||
//System.out.println("close");
|
||||
online=false;
|
||||
} catch (UnknownHostException e) {
|
||||
} catch (IOException e) {
|
||||
//e.printStackTrace();
|
||||
}
|
||||
if(!flag) {
|
||||
break;
|
||||
}
|
||||
try {
|
||||
synchronized (lock) {
|
||||
lock.wait(10000);
|
||||
}
|
||||
} 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,106 @@
|
||||
package org.kne.cloud.network.klalb;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import static org.kne.cloud.network.klalb.KLALBUtils.*;
|
||||
public class Monitor {
|
||||
|
||||
private AtomicLong inTraffic=new AtomicLong();
|
||||
private AtomicLong outTraffic=new AtomicLong();
|
||||
|
||||
|
||||
private AtomicLong inTrafficOld=new AtomicLong();
|
||||
private AtomicLong outTrafficOld=new AtomicLong();
|
||||
|
||||
private volatile long inSpeed;
|
||||
private volatile long outSpeed;
|
||||
|
||||
private volatile long inSpeedMax;
|
||||
private volatile long outSpeedMax;
|
||||
|
||||
private volatile long latency ;
|
||||
private volatile long jitter ;
|
||||
public long getInSpeedMax() {
|
||||
return inSpeedMax;
|
||||
}
|
||||
public void updateLatency(long newlatency) {
|
||||
long vj=Math.abs( latency-newlatency);;
|
||||
if(jitter<vj) {
|
||||
jitter=vj;
|
||||
}else {
|
||||
jitter=(9*jitter+vj)/10;
|
||||
}
|
||||
if(newlatency<latency) {
|
||||
latency=newlatency;
|
||||
}else {
|
||||
this.latency=(latency*9+ newlatency)/10;
|
||||
}
|
||||
}
|
||||
public long getOutSpeedMax() {
|
||||
return outSpeedMax;
|
||||
}
|
||||
|
||||
public long getInTraffic() {
|
||||
return inTraffic.get();
|
||||
}
|
||||
|
||||
public long getOutTraffic() {
|
||||
return outTraffic.get();
|
||||
}
|
||||
|
||||
public AtomicLong getInTrafficAL() {
|
||||
return inTraffic;
|
||||
}
|
||||
|
||||
public long getJitter() {
|
||||
return jitter;
|
||||
}
|
||||
public AtomicLong getOutTrafficAL() {
|
||||
return outTraffic;
|
||||
}
|
||||
|
||||
public long getInSpeed() {
|
||||
return inSpeed;
|
||||
}
|
||||
|
||||
|
||||
public long getOutSpeed() {
|
||||
return outSpeed;
|
||||
}
|
||||
|
||||
public void updateSpeed() {
|
||||
long i=inTraffic.get()-inTrafficOld.get();
|
||||
long o=outTraffic.get()-outTrafficOld.get();
|
||||
inTrafficOld.set(inTraffic.get());
|
||||
outTrafficOld.set(outTraffic.get());
|
||||
|
||||
inSpeed= i;
|
||||
outSpeed= o;
|
||||
|
||||
if(inSpeed>inSpeedMax) {
|
||||
inSpeedMax=inSpeed;
|
||||
}else {
|
||||
inSpeedMax=(inSpeedMax*999+inSpeed)/1000;
|
||||
}
|
||||
if(outSpeed>outSpeedMax) {
|
||||
outSpeedMax=outSpeed;
|
||||
}else {
|
||||
outSpeedMax=(outSpeedMax*999+outSpeed)/1000;
|
||||
}
|
||||
}
|
||||
|
||||
public long getLatency() {
|
||||
return latency;
|
||||
}
|
||||
public String toString() {
|
||||
StringBuilder sb=new StringBuilder();
|
||||
sb.append(bytesUnit(outTraffic.get())).append("\u2191\t").append(bytesUnit(inTraffic.get())).append("\u2193\t").append(bytesUnit(outSpeed)).append("/s\u2191\t").append(bytesUnit(inSpeed)).append("/s\u2193\t").append(latency/1000000).append("ms");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String toString2() {
|
||||
StringBuilder sb=new StringBuilder();
|
||||
sb.append(bytesUnit(outTraffic.get())).append("\t").append(bytesUnit(inTraffic.get())).append("\t").append(bytesUnit(outSpeed)).append("/s\t").append(bytesUnit(inSpeed)).append("/s\t").append(latency/1000000).append("ms").append("\t").append(jitter/1000000).append("ms");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,15 +1,15 @@
|
||||
package org.kne.cloud.network.klalb;
|
||||
|
||||
import java.io.FilterInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
public class MonitoredInputStream extends InputStream {
|
||||
public class MonitoredInputStream extends FilterInputStream {
|
||||
|
||||
private InputStream in;
|
||||
private AtomicLong[] total;
|
||||
public MonitoredInputStream(InputStream inputStream,AtomicLong... v) {
|
||||
this.in=inputStream;
|
||||
super(inputStream);
|
||||
this.total=v;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
package org.kne.cloud.network.klalb;
|
||||
|
||||
import java.io.FilterOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
public class MonitoredOutputStream extends OutputStream {
|
||||
public class MonitoredOutputStream extends FilterOutputStream {
|
||||
|
||||
private OutputStream out;
|
||||
private AtomicLong[] total;
|
||||
public MonitoredOutputStream(OutputStream outputStream,AtomicLong ...v) {
|
||||
this.out=outputStream;
|
||||
super(outputStream);
|
||||
this.total=v;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,68 +11,49 @@ import java.util.concurrent.atomic.AtomicLong;
|
||||
import org.kne.cloud.network.mport.FilterSocket;
|
||||
|
||||
public class MonitoredSocket extends FilterSocket {
|
||||
public Monitor getMonitor() {
|
||||
return monitor;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static Timer t=new Timer("带宽测量线程",true);
|
||||
|
||||
private Monitor monitor;
|
||||
private TimerTask ptt=new TimerTask() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
runMonitor();
|
||||
runMonitor();
|
||||
}
|
||||
};
|
||||
public MonitoredSocket(Socket socket) {
|
||||
this(socket,new Monitor());
|
||||
}
|
||||
public MonitoredSocket(Socket socket,Monitor monitor) {
|
||||
super(socket);
|
||||
t.scheduleAtFixedRate(ptt, 1000, 1000);
|
||||
this.monitor=monitor;
|
||||
}
|
||||
protected void runMonitor() {
|
||||
inSpeed.set( inTraffic.get()-inTrafficOld.get());
|
||||
outSpeed.set( outTraffic.get()-outTrafficOld.get());
|
||||
inTrafficOld.set(inTraffic.get());
|
||||
outTrafficOld.set(outTraffic.get());
|
||||
monitor.updateSpeed();
|
||||
|
||||
}
|
||||
public long getInTraffic() {
|
||||
return inTraffic.get();
|
||||
}
|
||||
|
||||
public long getOutTraffic() {
|
||||
return outTraffic.get();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public long getInSpeed() {
|
||||
return inSpeed.get();
|
||||
}
|
||||
|
||||
|
||||
public long getOutSpeed() {
|
||||
return outSpeed.get();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private InputStream in;
|
||||
private OutputStream out;
|
||||
private AtomicLong inTraffic=new AtomicLong();
|
||||
private AtomicLong outTraffic=new AtomicLong();
|
||||
|
||||
|
||||
private AtomicLong inTrafficOld=new AtomicLong();
|
||||
private AtomicLong outTrafficOld=new AtomicLong();
|
||||
|
||||
private AtomicLong inSpeed=new AtomicLong();
|
||||
private AtomicLong outSpeed=new AtomicLong();
|
||||
@Override
|
||||
public InputStream getInputStream() throws IOException {
|
||||
if(in==null)
|
||||
in=new MonitoredInputStream(socket.getInputStream(), inTraffic);
|
||||
in=new MonitoredInputStream(socket.getInputStream(), monitor.getInTrafficAL());
|
||||
return in;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream getOutputStream() throws IOException {
|
||||
if(out==null) {
|
||||
out=new MonitoredOutputStream(socket.getOutputStream(), outTraffic);
|
||||
out=new MonitoredOutputStream(socket.getOutputStream(), monitor.getOutTrafficAL());
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -1,13 +1,41 @@
|
||||
package org.kne.cloud.network.klalb;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
public class PINGPacket extends KLALBPacket {
|
||||
|
||||
|
||||
private long time;
|
||||
|
||||
@Override
|
||||
protected void writeToStream(DataOutput dto) throws IOException {
|
||||
super.writeToStream(dto);
|
||||
dto.writeLong(time);
|
||||
}
|
||||
|
||||
public long getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readFromStream(DataInput din) throws IOException {
|
||||
super.readFromStream(din);
|
||||
time=din.readLong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLength() {
|
||||
return super.getLength()+8;
|
||||
}
|
||||
|
||||
public PINGPacket() {
|
||||
super(PING);
|
||||
}
|
||||
|
||||
public PINGPacket(long time) {
|
||||
super(PING);
|
||||
this.time=time;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PING";
|
||||
|
||||
@@ -1,12 +1,43 @@
|
||||
package org.kne.cloud.network.klalb;
|
||||
|
||||
public class PONGPacket extends KLALBPacket {
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
public class PONGPacket extends KLALBPacket {
|
||||
public long getTime() {
|
||||
return time;
|
||||
}
|
||||
private long time;
|
||||
|
||||
@Override
|
||||
protected void writeToStream(DataOutput dto) throws IOException {
|
||||
super.writeToStream(dto);
|
||||
dto.writeLong(time);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readFromStream(DataInput din) throws IOException {
|
||||
super.readFromStream(din);
|
||||
time=din.readLong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLength() {
|
||||
return super.getLength()+8;
|
||||
}
|
||||
public PONGPacket() {
|
||||
super(PONG);
|
||||
}
|
||||
public PONGPacket(long time) {
|
||||
super(PONG);
|
||||
this.time=time;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PONG";
|
||||
}
|
||||
public void redeltaTime(long delta) {
|
||||
time+=delta;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ public class RSTPacket extends KLALBPacket {
|
||||
}
|
||||
|
||||
public RSTPacket() {
|
||||
super();
|
||||
super(RST);
|
||||
}
|
||||
|
||||
public int getSport() {
|
||||
|
||||
@@ -26,7 +26,7 @@ public class SACKTPacket extends KLALBPacket {
|
||||
}
|
||||
|
||||
public SACKTPacket() {
|
||||
super();
|
||||
super(SACKT);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -21,7 +21,7 @@ public class SYNTPacket extends KLALBPacket {
|
||||
}
|
||||
|
||||
public SYNTPacket() {
|
||||
super();
|
||||
super(SYNT);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,20 +1,33 @@
|
||||
package org.kne.cloud.network.klalb;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.NoRouteToHostException;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class SendTask extends TimerTask {
|
||||
public class SendTask {
|
||||
private int maxcount;
|
||||
private int count;
|
||||
private AtomicInteger count=new AtomicInteger();
|
||||
private int priority;
|
||||
private Inet6Address address;
|
||||
private volatile long starttime=System.nanoTime();
|
||||
private void resetTime() {
|
||||
starttime=System.nanoTime();
|
||||
}
|
||||
private boolean checkTime(long limit) {
|
||||
long curr=System.nanoTime();
|
||||
boolean b=curr-starttime>limit;
|
||||
if(b)
|
||||
starttime=curr;
|
||||
return b;
|
||||
}
|
||||
public SendTask( KLALBController controllker,Inet6Address address,DATATPacket kp,int priority,int maxcount) {
|
||||
super();
|
||||
this.maxcount = maxcount;
|
||||
this.controllker = controllker;
|
||||
this.kp = kp;
|
||||
this.packet = kp;
|
||||
this.address=address;
|
||||
this.priority=priority;
|
||||
}
|
||||
@@ -28,13 +41,13 @@ public class SendTask extends TimerTask {
|
||||
}
|
||||
|
||||
|
||||
public DATATPacket getKp() {
|
||||
return kp;
|
||||
public DATATPacket getPacket() {
|
||||
return packet;
|
||||
}
|
||||
|
||||
|
||||
private KLALBController controllker;
|
||||
private DATATPacket kp;
|
||||
private DATATPacket packet;
|
||||
|
||||
|
||||
public int getMaxcount() {
|
||||
@@ -43,25 +56,34 @@ public class SendTask extends TimerTask {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
public void check(int number) throws IOException {
|
||||
long limit= (1<<Math.min(4,count.get()-1))*(number<2?100:1000*number)*1000000L;
|
||||
if(checkTime(limit))
|
||||
run();
|
||||
}
|
||||
|
||||
|
||||
public void run() throws IOException {
|
||||
if(count.get()>=maxcount) {
|
||||
throw new IOException("send error!");
|
||||
}
|
||||
try {
|
||||
if(count.get()==0) {
|
||||
controllker.sendPacketToAddress((Inet6Address) address,
|
||||
kp, priority+count);
|
||||
packet, priority+count.get(),1);
|
||||
}else {
|
||||
controllker.sendPacketToAddress((Inet6Address) address,
|
||||
packet, priority+count.get(),2);
|
||||
}
|
||||
} catch (NoRouteToHostException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
count++;
|
||||
if(count>1) {
|
||||
System.out.println("重传:"+kp);
|
||||
}
|
||||
if(count>=maxcount) {
|
||||
cancel();
|
||||
resetTime();
|
||||
count.incrementAndGet();
|
||||
if(count.get()>1) {
|
||||
System.out.println("第"+(count.get()-1)+"次重传:"+packet);
|
||||
}
|
||||
|
||||
}
|
||||
public void addToTimer(int timeout) {
|
||||
controllker.getTimer().scheduleAtFixedRate(this, 0, timeout);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
package org.kne.cloud.network.klalb;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Properties;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ServerPropties extends Properties {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
public ServerPropties() throws IOException {
|
||||
super();
|
||||
load();
|
||||
}
|
||||
public void load() throws IOException {
|
||||
File f=new File("kserver.ini");
|
||||
if(!f.exists()||f.length()==0) {
|
||||
f.createNewFile();
|
||||
PrintStream ps=new PrintStream(f);
|
||||
ps.println("virtualip="+ KLALBUtils.uuidToIP(UUID.randomUUID()).getHostAddress());
|
||||
ps.println("bind=0.0.0.0:4568");
|
||||
ps.println("local=127.0.0.1:25565");
|
||||
ps.close();
|
||||
}
|
||||
FileReader fr = null;
|
||||
try {
|
||||
fr=new FileReader(f);
|
||||
load(fr);
|
||||
}finally {
|
||||
if(fr!=null)
|
||||
fr.close();
|
||||
}
|
||||
}
|
||||
public Inet6Address getVirtualIP() {
|
||||
try {
|
||||
return (Inet6Address) Inet6Address.getByName((String) get("virtualip"));
|
||||
} catch (UnknownHostException e) {
|
||||
// TODO 自动生成的 catch 块
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public String getBind() {
|
||||
return (String) get("bind");
|
||||
}
|
||||
|
||||
public String getLocal() {
|
||||
return (String) get("local");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package org.kne.cloud.network.klalb;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.Scanner;
|
||||
|
||||
import org.kne.cloud.network.klalb.LineManager.LineEntry;
|
||||
import org.kne.cloud.network.mport.MultipurposeSocketAddress;
|
||||
import org.kne.cloud.network.mport.SocketBridge;
|
||||
import org.kne.cloud.network.mport.TCPListener;
|
||||
import org.kne.util.AutoProperties;
|
||||
|
||||
public class SimpleKLALBClient {
|
||||
public static void main(String[] args) throws UnknownHostException, IOException {
|
||||
Scanner scn=new Scanner(System.in);
|
||||
Properties def=new Properties();
|
||||
def.setProperty("server", "");
|
||||
def.setProperty("local", "");
|
||||
AutoProperties ap=new AutoProperties(new File("klalbclient.ini"),def);
|
||||
KLALBController kc=new KLALBController();
|
||||
KLALBRemoteSocket kr=new KLALBRemoteSocket(new MultipurposeSocketAddress(ap.getProperty("server")).connectSocket());
|
||||
kc.addRemoteSocket(kr);
|
||||
kr.close();
|
||||
System.out.println("连接成功:"+ap.getProperty("server"));
|
||||
TCPListener tl=new TCPListener(new MultipurposeSocketAddress(ap.getProperty("local")));
|
||||
tl.setCon((s)->{
|
||||
KLALBVirtualSocket kvs=null;
|
||||
try {
|
||||
kvs=new KLALBVirtualSocket(kc, kr.getRemoteVaddr(), 23333);
|
||||
new SocketBridge(s, kvs).run();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}finally {
|
||||
|
||||
try {
|
||||
s.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if(kvs!=null)
|
||||
try {
|
||||
kvs.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
tl.open();
|
||||
System.out.println("提示:输入state并回车可以查看当前线路状态");
|
||||
while(true) {
|
||||
String s=scn.nextLine();
|
||||
switch(s) {
|
||||
case "state":
|
||||
System.out.println("状态\t上传流量\t下载流量\t上传速度\t下载速度\t延迟\t抖动");
|
||||
LineManager le=kc.getLineManager();
|
||||
for (Iterator<java.util.Map.Entry<MultipurposeSocketAddress, LineEntry>> iterator = le.entrySet().iterator(); iterator.hasNext();) {
|
||||
java.util.Map.Entry<MultipurposeSocketAddress, LineEntry> hostPort = iterator.next();
|
||||
System.out.println(hostPort.getValue() .toString2());
|
||||
//System.out.println();
|
||||
}
|
||||
break;
|
||||
default :
|
||||
System.out.println("未知命令!");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
package org.kne.cloud.network.klalb;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
|
||||
import org.kne.cloud.network.klalb.LineManager.LineEntry;
|
||||
import org.kne.cloud.network.mport.MultipurposeSocketAddress;
|
||||
import org.kne.cloud.network.mport.Protocol;
|
||||
import org.kne.cloud.network.mport.ProtocolDetectorServerSocketFactory;
|
||||
import org.kne.cloud.network.mport.ProtocolDetectorSocket;
|
||||
import org.kne.cloud.network.mport.ProxyProfileAnalyser;
|
||||
import org.kne.cloud.network.mport.ProxyProfileExecutor;
|
||||
import org.kne.cloud.network.mport.SocketBridge;
|
||||
import org.kne.cloud.network.mport.TCPListener;
|
||||
|
||||
public class SimpleKLALBServer {
|
||||
public static TCPListener tcpl,tcpl2;
|
||||
public static ServerPropties sp;
|
||||
public static KLALBController kc;
|
||||
static {
|
||||
MultipurposeSocketAddress.getServerSocketFactoryRegister().put("DETTCP", new ProtocolDetectorServerSocketFactory());
|
||||
}
|
||||
public static void main(String[] args) throws IOException {
|
||||
|
||||
System.out.println("KLALB负载均衡V2.0");
|
||||
sp=new ServerPropties();
|
||||
|
||||
System.out.println("虚拟地址:"+sp.getVirtualIP().getHostAddress());
|
||||
kc=new KLALBController(sp.getVirtualIP());
|
||||
kc.setSelflineTableSupplier(()->{
|
||||
return fileRead("linetable.txt");
|
||||
});
|
||||
kc.registerToProxyTypeAs("KLALB");
|
||||
|
||||
System.out.println("开放端口:"+sp.getBind());
|
||||
openPort(sp.getBind());
|
||||
System.out.println("本地服务:"+sp.getLocal());
|
||||
openLocalPort(sp.getLocal());
|
||||
|
||||
|
||||
|
||||
Scanner scn=new Scanner(System.in);
|
||||
while(true) {
|
||||
String s=scn.next();
|
||||
String[]sc=s.split(" ");
|
||||
switch(sc[0]) {
|
||||
case "help":
|
||||
System.out.print("state:查看线路状态");
|
||||
System.out.println("reload:重新加载线路配置");
|
||||
break;
|
||||
case "state":
|
||||
LineManager le=kc.getLineManager();
|
||||
for (Iterator<java.util.Map.Entry<MultipurposeSocketAddress, LineEntry>> iterator = le.entrySet().iterator(); iterator.hasNext();) {
|
||||
java.util.Map.Entry<MultipurposeSocketAddress, LineEntry> hostPort = iterator.next();
|
||||
System.out.println(hostPort.getValue() .toString());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
System.out.println("未知命令,请输入help以查询指令说明");
|
||||
}
|
||||
}
|
||||
}
|
||||
private static void openPort(String bip) throws IOException {
|
||||
if(tcpl!=null)
|
||||
tcpl.close();
|
||||
MultipurposeSocketAddress mpsa=new MultipurposeSocketAddress(bip,"DETTCP");
|
||||
tcpl=new TCPListener(mpsa);
|
||||
tcpl.setCon((soc)->{
|
||||
ProtocolDetectorSocket pds=(ProtocolDetectorSocket) soc;
|
||||
if(!pds.getProtocolStack().isEmpty()&&pds.getProtocolStack().pop().getName().equals("KLALB")) {
|
||||
KLALBRemoteSocket krs=new KLALBRemoteSocket(pds);
|
||||
kc.addRemoteSocket(krs);
|
||||
}else {
|
||||
MultipurposeSocketAddress mpsa2=new MultipurposeSocketAddress(sp.getLocal());
|
||||
Socket s=null;
|
||||
try {
|
||||
s=mpsa2.connectSocket();
|
||||
new SocketBridge(pds, s).run();
|
||||
} catch (UnknownHostException e) {
|
||||
// TODO 自动生成的 catch 块
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
// TODO 自动生成的 catch 块
|
||||
e.printStackTrace();
|
||||
}finally {
|
||||
if(s!=null)
|
||||
try {
|
||||
s.close();
|
||||
} catch (IOException e1) {
|
||||
// TODO 自动生成的 catch 块
|
||||
e1.printStackTrace();
|
||||
}
|
||||
try {
|
||||
soc.close();
|
||||
} catch (IOException e) {
|
||||
// TODO 自动生成的 catch 块
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
tcpl.open();
|
||||
}
|
||||
private static void openLocalPort(String bip) throws IOException {
|
||||
if(tcpl2!=null)
|
||||
tcpl2.close();
|
||||
MultipurposeSocketAddress mpsa=new MultipurposeSocketAddress(bip);
|
||||
tcpl2=new TCPListener(new MultipurposeSocketAddress("KLALB", "::0", 23333));
|
||||
tcpl2.setCon((soc)->{
|
||||
Socket s=null;
|
||||
try {
|
||||
s=mpsa.connectSocket();
|
||||
new SocketBridge(soc, s).run();
|
||||
} catch (UnknownHostException e) {
|
||||
// TODO 自动生成的 catch 块
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
// TODO 自动生成的 catch 块
|
||||
e.printStackTrace();
|
||||
}finally {
|
||||
if(s!=null)
|
||||
try {
|
||||
s.close();
|
||||
} catch (IOException e1) {
|
||||
// TODO 自动生成的 catch 块
|
||||
e1.printStackTrace();
|
||||
}
|
||||
try {
|
||||
soc.close();
|
||||
} catch (IOException e) {
|
||||
// TODO 自动生成的 catch 块
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
tcpl2.open();
|
||||
}
|
||||
private static String fileRead(String filePath){
|
||||
//1.定义一个BufferedReader对象,将文件内容读取到缓存
|
||||
BufferedReader bufferedReader =null;
|
||||
String returnInfo="";
|
||||
try{
|
||||
// 2.定义一个file对象
|
||||
File file = new File(filePath);//定义一个file对象,用来初始化FileReader
|
||||
// 3.定义一个fileReader对象
|
||||
FileReader reader = new FileReader(file);
|
||||
// 4.定义一个BufferedReader对象,将文件内容读取到缓存
|
||||
bufferedReader = new BufferedReader(reader);
|
||||
// 5.定义一个字符串缓存,将字符串存放缓存中
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
String str = "";
|
||||
while ((str =bufferedReader.readLine()) != null) {//逐行读取文件内容,不读取换行符和末尾的空格
|
||||
stringBuilder.append(str + "\n");//将读取的字符串添加换行符后累加存放在缓存中
|
||||
}
|
||||
returnInfo = stringBuilder.toString();
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
}finally {
|
||||
try{
|
||||
if(bufferedReader!=null){
|
||||
bufferedReader.close();
|
||||
}
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return returnInfo;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,12 +17,12 @@ public class VADDRPacket extends KLALBPacket {
|
||||
}
|
||||
|
||||
public VADDRPacket() {
|
||||
super();
|
||||
super(VADDR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "VADDR"+vaddr;
|
||||
return "VADDR "+vaddr.getHostAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user