forked from KNEMC/KLALB
KLALB大更新
新负载均衡算法
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user