TCP连接池功能
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 2.9 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.8 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.7 KiB |
@@ -1,7 +1,9 @@
|
|||||||
package org.kne.cloud.network.klalb;
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
public class Consts {
|
public class Consts {
|
||||||
public static final int BLOCKSIZE=65536;
|
public static final int BLOCKSIZE=32768;
|
||||||
public static final long PINGTIMENS=10000000000L;
|
public static final long PINGTIMENS=10000000000L;
|
||||||
public static final double A = 0.125;
|
public static final double A = 0.125;
|
||||||
|
public static final int SO_TIMEOUT = 20000;
|
||||||
|
public static final long SN_KEEP = 60000000000L;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,149 +4,90 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
import java.util.WeakHashMap;
|
||||||
|
|
||||||
|
import org.kne.cloud.network.mport.ServiceElement;
|
||||||
import org.kne.cloud.network.mport.ThreadTool;
|
import org.kne.cloud.network.mport.ThreadTool;
|
||||||
|
|
||||||
public class IOThreadManager {
|
public class IOThreadManager {
|
||||||
private KLALBCore klc=new KLALBCore(10000);
|
private KLALBCore klc = new KLALBCore(5000);
|
||||||
private List<TCPConnection>tcps=new Vector<>();
|
private boolean isopen = true;
|
||||||
|
|
||||||
|
|
||||||
private TCPConnection local;
|
|
||||||
|
|
||||||
|
|
||||||
private volatile boolean open=true;
|
public void handleLocal(LocalTCPConnection tc, ServiceElement se,boolean syn) {
|
||||||
public void startLocal() {
|
klc.getLocaltcps().add(tc);
|
||||||
|
|
||||||
Thread upo=ThreadTool.makeVThreadIfSupport("本地接收线程",()->{
|
|
||||||
try{
|
|
||||||
|
|
||||||
while(true) {
|
|
||||||
byte[]b=new byte[Consts.BLOCKSIZE];
|
|
||||||
int size=local.getDin().read(b);
|
|
||||||
if(size==-1)
|
|
||||||
break;
|
|
||||||
klc.packDataBlock(b,size);
|
|
||||||
}
|
|
||||||
klc.waitForRemote();
|
|
||||||
}catch(InterruptedException s) {
|
|
||||||
}catch(SocketException se) {
|
|
||||||
}catch(Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}finally {
|
|
||||||
closeRemote();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Thread downo=ThreadTool.makeVThreadIfSupport("本地发送线程",()->{
|
|
||||||
try{
|
|
||||||
while(true) {
|
|
||||||
|
|
||||||
local.getDout().write(klc.unpackDataBlock());
|
|
||||||
local.getDout().flush();
|
|
||||||
}
|
|
||||||
}catch(InterruptedException s) {
|
|
||||||
}catch(Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}finally {
|
|
||||||
}
|
|
||||||
});
|
|
||||||
upo.start();
|
|
||||||
downo.start();
|
|
||||||
}
|
|
||||||
public void handleSocket(TCPConnection s) throws IOException {
|
|
||||||
tcps.add(s);
|
|
||||||
try {
|
try {
|
||||||
Thread up=ThreadTool.makeVThreadIfSupport("远程发送线程",()->{
|
if(syn) {
|
||||||
try{
|
KLALBBlock sbk=new KLALBBlock();
|
||||||
while(true) {
|
sbk.cuid=tc.getCuid();
|
||||||
if(s.getTunnel().getName().contains("Openfrp")) {
|
sbk.number=0;
|
||||||
klc.sendDataBlockControlOnly(s);
|
sbk.command=2;
|
||||||
}else {
|
sbk.lservice=se.proc;
|
||||||
klc.sendDataBlock(s);
|
sbk.lipport=se.ipport;
|
||||||
}
|
klc.submitDataBlockNoDelay(sbk);
|
||||||
}
|
}
|
||||||
}catch(InterruptedException s1) {
|
Thread ls = ThreadTool.makeVThreadIfSupport("本地发送线程", () -> {
|
||||||
|
|
||||||
}catch(Exception e) {
|
});
|
||||||
e.printStackTrace();
|
Thread lr = ThreadTool.makeVThreadIfSupport("本地接收线程", () -> {
|
||||||
}
|
|
||||||
});
|
});
|
||||||
Thread down=ThreadTool.makeVThreadIfSupport("远程接收线程",()->{
|
ls.start();
|
||||||
try{
|
lr.start();
|
||||||
while(true) {
|
ls.join();
|
||||||
klc.receiveDataBlock(s);
|
lr.join();
|
||||||
}
|
} catch (InterruptedException e) {
|
||||||
}catch(InterruptedException s1) {
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
}catch(Exception e) {
|
klc.getLocaltcps().remove(tc);
|
||||||
up.interrupt();
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleRemote(RemoteTCPConnection tc) {
|
||||||
|
klc.getRemotetcps().add(tc);
|
||||||
|
try {
|
||||||
|
Thread rs = ThreadTool.makeVThreadIfSupport("远程发送线程", () -> {
|
||||||
|
|
||||||
|
try {
|
||||||
|
while (true) {
|
||||||
|
klc.remoteSend(tc);
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Thread rr = ThreadTool.makeVThreadIfSupport("远程接收线程", () -> {
|
||||||
|
try {
|
||||||
|
while (true) {
|
||||||
|
klc.remoteReceive(tc);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
rs.start();
|
||||||
|
rr.start();
|
||||||
|
rs.join();
|
||||||
|
rr.join();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
klc.getRemotetcps().remove(tc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
up.start();
|
public void close() {
|
||||||
down.start();
|
isopen = false;
|
||||||
try {
|
|
||||||
down.join();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}finally {
|
|
||||||
tcps.remove(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void closeRemote() {
|
|
||||||
open=false;
|
|
||||||
|
|
||||||
for (int i = 0; i < tcps.size(); i++) {
|
|
||||||
TCPConnection tll=tcps.get(i);
|
|
||||||
tll.close();
|
|
||||||
}
|
|
||||||
klc.closeRemote();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void closeLocal() {
|
|
||||||
open=false;
|
|
||||||
local.close();
|
|
||||||
klc.closeLocal();
|
|
||||||
}
|
|
||||||
|
|
||||||
public TCPConnection getLocal() {
|
|
||||||
return local;
|
|
||||||
}
|
|
||||||
public void setLocal(TCPConnection local) {
|
|
||||||
this.local = local;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
public void closeALL() {
|
|
||||||
open=false;
|
|
||||||
|
|
||||||
for (int i = 0; i < tcps.size(); i++) {
|
|
||||||
TCPConnection tll=tcps.get(i);
|
|
||||||
tll.close();
|
|
||||||
}
|
|
||||||
klc.closeRemote();
|
|
||||||
klc.closeLocal();
|
|
||||||
try {
|
|
||||||
in.close();
|
|
||||||
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
out.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
public List<TCPConnection> getTcps() {
|
|
||||||
return tcps;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isOpen() {
|
public boolean isOpen() {
|
||||||
return open;
|
return isopen;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,50 +2,58 @@ package org.kne.cloud.network.klalb;
|
|||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
|
import org.kne.cloud.network.mport.IPPort;
|
||||||
|
|
||||||
public class KLALBBlock {
|
public class KLALBBlock {
|
||||||
volatile byte[]data;
|
private static AtomicLong sng=new AtomicLong(0);
|
||||||
volatile int size;
|
|
||||||
volatile long number;
|
public long sn;//每个数据包的唯一编号
|
||||||
|
public UUID cuid;//用于识别数据包的stream ID号
|
||||||
|
public long number;//数据包的编号,用于排序
|
||||||
volatile long time=-1;
|
public byte[]data;//数据内容
|
||||||
volatile TCPConnection connect;
|
public int command;//功能标记 0=PING 1=PONG 2=SYN 3=RST
|
||||||
public KLALBBlock(byte[] b, int size,long number) {
|
public long pingtime;//PING计时器
|
||||||
data=b;
|
|
||||||
this.size=size;
|
public String lservice;
|
||||||
this.number=number;
|
public IPPort lipport;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public KLALBBlock() {
|
public KLALBBlock() {
|
||||||
// TODO 自动生成的构造函数存根
|
sn=sng.getAndIncrement();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
StringBuilder sb=new StringBuilder();
|
||||||
|
sb.append(cuid);
|
||||||
|
sb.append(' ');
|
||||||
if(number>0) {
|
if(number>0) {
|
||||||
return "DATA"+number+":"+size;
|
sb.append("DATA").append(number).append(':').append(data.length);
|
||||||
}else if(number==0){
|
}else if(number<0) {
|
||||||
return "PING";
|
sb.append("ACK").append(-number);
|
||||||
}else if(number==Long.MIN_VALUE){
|
|
||||||
return "PONG";
|
|
||||||
}else {
|
}else {
|
||||||
return "ACK"+(-number);
|
switch(command) {
|
||||||
|
case 0:
|
||||||
|
sb.append("PING");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
sb.append("PONG");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
sb.append("SYN:").append(lservice).append(" ").append(lipport);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
sb.append("RST");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return sb.toString();
|
||||||
}
|
}
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(number);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (this == obj)
|
|
||||||
return true;
|
|
||||||
if (obj == null)
|
|
||||||
return false;
|
|
||||||
if (getClass() != obj.getClass())
|
|
||||||
return false;
|
|
||||||
KLALBBlock other = (KLALBBlock) obj;
|
|
||||||
return number == other.number;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import java.io.BufferedInputStream;
|
|||||||
import java.io.BufferedOutputStream;
|
import java.io.BufferedOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.ConnectException;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
@@ -21,111 +22,68 @@ import org.kne.cloud.network.mport.ServiceElement;
|
|||||||
import org.kne.cloud.network.mport.ThreadTool;
|
import org.kne.cloud.network.mport.ThreadTool;
|
||||||
|
|
||||||
public class KLALBClient {
|
public class KLALBClient {
|
||||||
private static Object olock=new Object();
|
|
||||||
static {
|
UUID suid=UUID.randomUUID();
|
||||||
new Thread(()->{
|
IOThreadManager iom=new IOThreadManager();
|
||||||
while(true) {
|
|
||||||
try {
|
|
||||||
Thread.sleep(10000);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
synchronized(olock) {
|
|
||||||
olock.notifyAll();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).start();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private List<Tunnel> tls=new ArrayList<>();
|
private List<Tunnel> tls=new ArrayList<>();
|
||||||
private TCPListener tcpl;
|
private TCPListener tcpl;
|
||||||
private ServiceElement sel;
|
private ServiceElement sel;
|
||||||
|
|
||||||
public void runProtocol(IOThreadManager kcp, UUID uid) {
|
|
||||||
AtomicBoolean b=new AtomicBoolean(true);
|
|
||||||
AtomicInteger aig=new AtomicInteger(0);
|
|
||||||
for (int i = 0; i < tls.size(); i++) {
|
|
||||||
Tunnel tll=tls.get(i);
|
|
||||||
ThreadTool.makeVThreadIfSupport("隧道监视线程",()->{
|
|
||||||
while (kcp.isOpen()) {
|
|
||||||
try {
|
|
||||||
TCPConnection tc=new TCPConnection(tll);
|
|
||||||
tc.getDout().writeShort(59649);
|
|
||||||
tc.getDout().write(1);
|
|
||||||
|
|
||||||
tc.getDout().writeUTF(sel.ipport.getIp().getHostAddress());
|
|
||||||
tc.getDout().writeInt(sel.ipport.getPort());
|
|
||||||
tc.getDout().writeUTF(sel.proc);
|
|
||||||
|
|
||||||
tc.getDout().writeUTF(tll.getName());
|
|
||||||
tc.getDout().writeUTF(tll.getIp());
|
|
||||||
tc.getDout().writeInt(tll.getPort());
|
|
||||||
tc.getDout().writeLong(uid.getMostSignificantBits());
|
|
||||||
tc.getDout().writeLong(uid.getLeastSignificantBits());
|
|
||||||
tc.getDout().flush();
|
|
||||||
aig.incrementAndGet();
|
|
||||||
System.out.println("隧道"+tll+"已连接,可用线路数量:"+ (kcp.getTcps().size()+1));
|
|
||||||
try {
|
|
||||||
kcp.handleSocket(tc);
|
|
||||||
|
|
||||||
}catch(IOException e){
|
|
||||||
e.printStackTrace();
|
|
||||||
}finally {
|
|
||||||
tc.close();
|
|
||||||
}
|
|
||||||
int n=kcp.getTcps().size();
|
|
||||||
System.out.println("隧道"+tll+"已断开,可用线路数量:"+ n);
|
|
||||||
if(n<=0) {
|
|
||||||
kcp.closeRemote();
|
|
||||||
kcp.closeLocal();
|
|
||||||
System.out.println("连接已断开");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
if(aig.get()<=0) {
|
|
||||||
kcp.closeRemote();
|
|
||||||
kcp.closeLocal();
|
|
||||||
if(b.get()) {
|
|
||||||
System.out.println("隧道连接失败");
|
|
||||||
b.set(false);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized(olock) {
|
|
||||||
try {
|
|
||||||
olock.wait();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).start();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
public void open(int port) throws IOException {
|
public void open(int port) throws IOException {
|
||||||
tcpl=new TCPListener(port);
|
tcpl=new TCPListener(port);
|
||||||
tcpl.setCon((s)->{
|
tcpl.setCon((s)->{
|
||||||
IOThreadManager kcp=new IOThreadManager();
|
LocalTCPConnection tcc = null;
|
||||||
UUID uid=UUID.randomUUID();
|
try {
|
||||||
|
tcc = new LocalTCPConnection(s);
|
||||||
|
System.out.println("TCP:"+tcc.getCuid()+"已连接");
|
||||||
|
iom.handleLocal(tcc,sel,true);
|
||||||
|
System.out.println("TCP:"+tcc.getCuid()+"已关闭");
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}finally {
|
||||||
|
if(tcc!=null) {
|
||||||
|
tcc.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
tcpl.open();
|
||||||
|
for (int i = 0; i < tls.size(); i++) {
|
||||||
|
Tunnel tll=tls.get(i);
|
||||||
|
ThreadTool.makeVThreadIfSupport("隧道监视线程", ()->{
|
||||||
|
RemoteTCPConnection tc=null;
|
||||||
|
while(iom.isOpen()) {
|
||||||
try {
|
try {
|
||||||
kcp.setLocal(new TCPConnection(null, s));
|
tc=new RemoteTCPConnection(tll);
|
||||||
kcp.startLocal();
|
tc.getDout().writeShort(59649);
|
||||||
runProtocol(kcp,uid);
|
tc.getDout().write(1);
|
||||||
|
tc.getDout().writeUTF(tll.getName());
|
||||||
|
tc.getDout().writeUTF(tll.getIp());
|
||||||
|
tc.getDout().writeInt(tll.getPort());
|
||||||
|
tc.getDout().writeLong(suid.getMostSignificantBits());
|
||||||
|
tc.getDout().writeLong(suid.getLeastSignificantBits());
|
||||||
|
tc.getDout().flush();
|
||||||
|
System.out.println(tll+":连接成功");
|
||||||
|
iom.handleRemote(tc);
|
||||||
|
System.out.println(tll+":连接断开");
|
||||||
|
} catch (UnknownHostException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}catch(ConnectException e) {
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
}finally {
|
||||||
|
if(tc!=null)
|
||||||
|
tc.close();
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
});
|
Thread.sleep(5000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
tcpl.open();
|
}
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
public List<Tunnel> getTls() {
|
public List<Tunnel> getTls() {
|
||||||
return tls;
|
return tls;
|
||||||
@@ -139,7 +97,7 @@ public class KLALBClient {
|
|||||||
IPPort u=new IPPort(ipport);
|
IPPort u=new IPPort(ipport);
|
||||||
TCPConnection tcpc=null;
|
TCPConnection tcpc=null;
|
||||||
try {
|
try {
|
||||||
tcpc=new TCPConnection(null, new Socket(u.getIp(),u.getPort()));
|
tcpc=new RemoteTCPConnection(null, new Socket(u.getIp(),u.getPort()));
|
||||||
tcpc.getDout().writeShort(59649);
|
tcpc.getDout().writeShort(59649);
|
||||||
tcpc.getDout().write(0);
|
tcpc.getDout().write(0);
|
||||||
tcpc.getDout().flush();
|
tcpc.getDout().flush();
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
|
||||||
|
import org.kne.ui.XFrame;
|
||||||
|
|
||||||
|
public class KLALBClientGUI extends XFrame{
|
||||||
|
public KLALBClientGUI() {
|
||||||
|
setResizable(false);
|
||||||
|
setTitleColor(new Color(0,0,255,128));
|
||||||
|
getContentPane().setBackground(new Color(128,128,255,128));
|
||||||
|
setTitle("KNE云网络负载均衡客户端");
|
||||||
|
setSize(600,370);
|
||||||
|
setLocationRelativeTo(null);
|
||||||
|
setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
new KLALBClientGUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -13,9 +13,11 @@ import java.util.Iterator;
|
|||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
import java.util.WeakHashMap;
|
import java.util.WeakHashMap;
|
||||||
import java.util.concurrent.ArrayBlockingQueue;
|
import java.util.concurrent.ArrayBlockingQueue;
|
||||||
@@ -25,294 +27,154 @@ import java.util.concurrent.ExecutorService;
|
|||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
import org.kne.cloud.network.mport.ThreadTool;
|
import org.kne.cloud.network.mport.ThreadTool;
|
||||||
|
|
||||||
public class KLALBCore {
|
public class KLALBCore {
|
||||||
private volatile long inputcount = 1;
|
private static final UUID ZERO_UUID=new UUID(0,0);
|
||||||
private volatile long outputcount = 1;
|
|
||||||
private Set<KLALBBlock> inputcache = Collections.synchronizedSet(new HashSet<>());
|
|
||||||
private List<KLALBBlock> outputcache = new Vector<>();
|
|
||||||
|
|
||||||
private BlockingQueue<KLALBBlock> ackp=new LinkedBlockingQueue<>();
|
|
||||||
private BlockingQueue<KLALBBlock> ackq=new LinkedBlockingQueue<>();
|
|
||||||
private volatile boolean inlocal=true;
|
|
||||||
|
|
||||||
private volatile boolean closeremote = false;
|
|
||||||
private volatile boolean closelocal = false;
|
|
||||||
|
|
||||||
private volatile int cacheblocks;
|
private volatile int cacheblocks;
|
||||||
|
|
||||||
|
|
||||||
|
private List<LocalTCPConnection> localtcps = new Vector<>();
|
||||||
|
private List<RemoteTCPConnection> remotetcps = new Vector<>();
|
||||||
|
private Predicate<KLALBBlock>acceptSYN;
|
||||||
|
|
||||||
|
|
||||||
|
private volatile long rsntime=System.nanoTime();
|
||||||
|
private Set<SN> rsns=Collections.synchronizedSet(new HashSet<SN>());
|
||||||
|
private static class SN{
|
||||||
|
volatile long sn;
|
||||||
|
volatile long time;
|
||||||
|
public SN(long sn) {
|
||||||
|
super();
|
||||||
|
this.sn = sn;
|
||||||
|
this.time=System.nanoTime();
|
||||||
|
}
|
||||||
|
public boolean isVaild() {
|
||||||
|
return System.nanoTime()-time<=Consts.SN_KEEP;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(sn);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
SN other = (SN) obj;
|
||||||
|
return sn == other.sn;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Predicate<KLALBBlock> getAcceptSYN() {
|
||||||
|
return acceptSYN;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAcceptSYN(Predicate<KLALBBlock> acceptSYN) {
|
||||||
|
this.acceptSYN = acceptSYN;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<LocalTCPConnection> getLocaltcps() {
|
||||||
|
return localtcps;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<RemoteTCPConnection> getRemotetcps() {
|
||||||
|
return remotetcps;
|
||||||
|
}
|
||||||
|
|
||||||
public KLALBCore(int cachesize) {
|
public KLALBCore(int cachesize) {
|
||||||
cacheblocks=cachesize;
|
cacheblocks=cachesize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void packDataBlock(byte[] b, int size) throws InterruptedException {
|
public void remoteSend(RemoteTCPConnection tc) throws InterruptedException, IOException {
|
||||||
|
for(;;) {
|
||||||
if (closelocal)
|
if(tc.checkPingTime()) {
|
||||||
throw new InterruptedException();
|
KLALBBlock pdb=new KLALBBlock();
|
||||||
while (!outputcache.isEmpty()&&(outputcount-outputcache.get(0).number>cacheblocks)) {
|
pdb.cuid=ZERO_UUID;
|
||||||
if (closelocal)
|
pdb.number=0;
|
||||||
Thread.currentThread().interrupt();
|
pdb.command=0;
|
||||||
|
pdb.pingtime=System.nanoTime();
|
||||||
|
tc.sendBlock(pdb);
|
||||||
|
}
|
||||||
|
if(!tc.getSendDeque().isEmpty())
|
||||||
|
break;
|
||||||
Thread.sleep(1);
|
Thread.sleep(1);
|
||||||
}
|
}
|
||||||
outputcache.add(new KLALBBlock(b, size, outputcount++));
|
KLALBBlock k=tc.getSendDeque().poll();
|
||||||
|
if(k!=null) {
|
||||||
|
tc.sendBlock(k);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
public void remoteReceive(RemoteTCPConnection tc) throws IOException {
|
||||||
public byte[] unpackDataBlock() throws InterruptedException {
|
KLALBBlock brc=null;
|
||||||
inlocal=false;
|
for(;;) {
|
||||||
try {
|
brc=tc.receiveBlock();
|
||||||
if (closelocal)
|
SN s=new SN(brc.sn);
|
||||||
throw new InterruptedException();
|
synchronized (rsns) {
|
||||||
byte[] b = null;
|
if(!rsns.contains(s)) {
|
||||||
while (true) {
|
rsns.add(s);
|
||||||
synchronized (inputcache) {
|
break;
|
||||||
Iterator<KLALBBlock> klb = inputcache.iterator();
|
}
|
||||||
while (klb.hasNext()) {
|
}
|
||||||
KLALBBlock klalbBlock = (KLALBBlock) klb.next();
|
}
|
||||||
if (klalbBlock.number < inputcount) {
|
synchronized (rsns) {
|
||||||
klb.remove();
|
long ctime=System.nanoTime();
|
||||||
} else if (klalbBlock.number == inputcount) {
|
if(ctime-rsntime>10000000000L) {
|
||||||
b = klalbBlock.data;
|
rsntime=ctime;
|
||||||
klb.remove();
|
for (Iterator<SN> iterator = rsns.iterator(); iterator.hasNext();) {
|
||||||
}
|
SN sn = (SN) iterator.next();
|
||||||
|
if(!sn.isVaild()) {
|
||||||
|
iterator.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (b != null) {
|
|
||||||
System.out.println("\tSORT:"+inputcount+" " + inputcache.size());
|
|
||||||
inputcount++;
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
if (closelocal)
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
Thread.sleep(1);
|
|
||||||
//System.err.println(inputcount);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}finally {
|
|
||||||
inlocal=true;
|
|
||||||
}
|
}
|
||||||
}
|
if(brc.cuid.equals(ZERO_UUID)) {
|
||||||
|
if(brc.number==0) {
|
||||||
private void makeAck(KLALBBlock klalbBlock) {
|
if(brc.command==0) {
|
||||||
KLALBBlock klb1=new KLALBBlock(null, 0, -klalbBlock.number);
|
KLALBBlock pdb=new KLALBBlock();
|
||||||
klb1.time=klalbBlock.time;
|
pdb.cuid=ZERO_UUID;
|
||||||
ackq.add(klb1);
|
pdb.number=0;
|
||||||
if(ackp.size()<100) {
|
pdb.command=1;
|
||||||
KLALBBlock klb2=new KLALBBlock(null, 0, -klalbBlock.number);
|
pdb.pingtime=brc.pingtime;
|
||||||
klb2.time=klalbBlock.time;
|
tc.getSendDeque().addFirst(pdb);
|
||||||
ackp.add(klb2);
|
}else if(brc.command==1) {
|
||||||
}
|
long cur=System.nanoTime();
|
||||||
}
|
long delay=(cur-brc.pingtime)/2;
|
||||||
|
tc.setDelay(delay);
|
||||||
|
|
||||||
public void sendDataBlock(TCPConnection out) throws IOException, InterruptedException {
|
|
||||||
if (closeremote)
|
|
||||||
throw new InterruptedException();
|
|
||||||
//BlockingQueue<KLALBBlock> bqk=acks.get(out);
|
|
||||||
while (ackq.isEmpty()&& outputcache.isEmpty()) {
|
|
||||||
if (closeremote)
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
Thread.sleep(1);
|
|
||||||
if(out.checkPingTime()) {
|
|
||||||
send0(out, new KLALBBlock(null,0 , 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
KLALBBlock klb=ackq.poll();
|
|
||||||
if(klb!=null) {
|
|
||||||
send0(out, klb);
|
|
||||||
}else {
|
|
||||||
KLALBBlock ks = null;
|
|
||||||
synchronized (outputcache) {
|
|
||||||
for (int i = 0; i < outputcache.size(); i++) {
|
|
||||||
|
|
||||||
KLALBBlock kd = outputcache.get(i);
|
|
||||||
if (kd.connect == null) {
|
|
||||||
kd.time = System.nanoTime();
|
|
||||||
kd.connect = out;
|
|
||||||
ks = kd;
|
|
||||||
} else {
|
|
||||||
if (kd.connect.isOpen()) {
|
|
||||||
long timex = (System.nanoTime() - kd.time) / 1000000;
|
|
||||||
if (timex > 100+1000*i) {
|
|
||||||
kd.time = System.nanoTime();
|
|
||||||
kd.connect = out;
|
|
||||||
ks = kd;
|
|
||||||
System.out.println("³¬Ê±ÖØ´«£º"+kd);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
kd.time = System.nanoTime();
|
|
||||||
kd.connect = out;
|
|
||||||
ks = kd;
|
|
||||||
System.out.println("µôÏßÖØ´«£º"+kd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ks != null) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ks != null) {
|
}else {
|
||||||
send0(out, ks);
|
if(brc.number==0) {
|
||||||
ks.time = System.nanoTime();
|
if(brc.command==0) {
|
||||||
}else {
|
}else if(brc.command==1) {
|
||||||
Thread.sleep(1);
|
}else if(brc.command==2) {
|
||||||
}
|
if(acceptSYN==null||!acceptSYN.test(brc)) {
|
||||||
}
|
KLALBBlock rst=new KLALBBlock();
|
||||||
|
rst.cuid=brc.cuid;
|
||||||
if(out.checkPingTime()) {
|
rst.number=0;
|
||||||
send0(out, new KLALBBlock(null,0 , 0));
|
rst.command=3;
|
||||||
}
|
submitDataBlockNoDelay(rst);
|
||||||
}
|
|
||||||
|
|
||||||
public void sendDataBlockControlOnly(TCPConnection out) throws IOException, InterruptedException {
|
|
||||||
if (closeremote)
|
|
||||||
throw new InterruptedException();
|
|
||||||
//BlockingQueue<KLALBBlock> bqk=acks.get(out);
|
|
||||||
while (ackp.isEmpty()) {
|
|
||||||
if (closeremote)
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
Thread.sleep(1);
|
|
||||||
if(out.checkPingTime()) {
|
|
||||||
send0(out, new KLALBBlock(null,0 , 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
KLALBBlock klb=ackp.poll();
|
|
||||||
if(klb!=null) {
|
|
||||||
send0(out, klb);
|
|
||||||
//System.out.println(klb+" "+ackp.size());
|
|
||||||
}
|
|
||||||
if(out.checkPingTime()) {
|
|
||||||
send0(out, new KLALBBlock(null,0 , 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void receiveDataBlock(TCPConnection in) throws IOException, InterruptedException {
|
|
||||||
if (closeremote)
|
|
||||||
throw new InterruptedException();
|
|
||||||
KLALBBlock x = receive0(in);
|
|
||||||
long rect=System.nanoTime();
|
|
||||||
if (x.number > 0) {
|
|
||||||
|
|
||||||
/*BlockingQueue<KLALBBlock> bq=acks.get(in);
|
|
||||||
if(bq==null) {
|
|
||||||
BlockingQueue<KLALBBlock> bqt=new LinkedBlockingQueue<>();
|
|
||||||
bqt.add(klb);
|
|
||||||
acks.put(in,bqt);
|
|
||||||
}else {
|
|
||||||
acks.get(in).add(klb);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
if (x.number >= inputcount) {
|
|
||||||
|
|
||||||
while(inputcache.size()>(2*cacheblocks)&&inlocal) {
|
|
||||||
if (closeremote)
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
Thread.sleep(1);
|
|
||||||
}
|
}
|
||||||
|
}else if(brc.command==3) {
|
||||||
inputcache.add(x);
|
|
||||||
}
|
}
|
||||||
makeAck(x);
|
|
||||||
|
|
||||||
} else if(x.number==0) {
|
|
||||||
ThreadTool.makeVThreadIfSupport("TACK", ()->{
|
|
||||||
try {
|
|
||||||
KLALBBlock klk=new KLALBBlock(null,0,Long.MIN_VALUE);
|
|
||||||
long st=System.nanoTime();
|
|
||||||
long tw=st-rect;
|
|
||||||
klk.time=x.time+tw;
|
|
||||||
send0(in, klk);
|
|
||||||
} catch (IOException e) {
|
|
||||||
}finally {
|
|
||||||
}
|
}
|
||||||
}).start();
|
|
||||||
}else if(x.number==Long.MIN_VALUE){
|
|
||||||
//System.out.println("PING:"+(System.nanoTime()-x.time)/2000000);
|
|
||||||
long del=(System.nanoTime()-x.time)/2;
|
|
||||||
in.setDelay(del);
|
|
||||||
}else{
|
|
||||||
long v = -x.number;
|
|
||||||
outputcache.removeIf((b) -> {
|
|
||||||
return b.number == v;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public void submitDataBlock(KLALBBlock kb) {
|
||||||
private void send0(TCPConnection tcp, KLALBBlock kd) throws IOException {
|
|
||||||
DataOutputStream out=tcp.getDout();
|
|
||||||
synchronized (out) {
|
|
||||||
|
|
||||||
out.writeLong(kd.number);
|
|
||||||
if (kd.number > 0) {
|
|
||||||
out.writeLong(System.nanoTime());
|
|
||||||
out.writeInt(kd.size);
|
|
||||||
out.write(kd.data, 0, kd.size);
|
|
||||||
}else if(kd.number==0){
|
|
||||||
out.writeLong(System.nanoTime());
|
|
||||||
}else if(kd.number==Long.MIN_VALUE) {
|
|
||||||
out.writeLong(kd.time);
|
|
||||||
}else {
|
|
||||||
out.writeLong(kd.time);
|
|
||||||
}
|
|
||||||
out.flush();
|
|
||||||
|
|
||||||
}
|
|
||||||
System.out.println(tcp.getTunnel().getName()+" SEND:" + kd);
|
|
||||||
}
|
}
|
||||||
|
public void submitDataBlockNoDelay(KLALBBlock kb) {
|
||||||
private KLALBBlock receive0(TCPConnection tcp) throws IOException {
|
synchronized (remotetcps) {
|
||||||
KLALBBlock kb = new KLALBBlock();
|
for (Iterator<RemoteTCPConnection> iterator = remotetcps.iterator(); iterator.hasNext();) {
|
||||||
DataInputStream in=tcp.getDin();
|
RemoteTCPConnection rmt = (RemoteTCPConnection) iterator.next();
|
||||||
synchronized (in) {
|
rmt.getSendDeque().addFirst(kb);
|
||||||
|
|
||||||
kb.number = in.readLong();
|
|
||||||
if (kb.number > 0) {
|
|
||||||
kb.time=in.readLong();
|
|
||||||
kb.size = in.readInt();
|
|
||||||
if(kb.size<0||kb.size>65536) {
|
|
||||||
throw new StreamCorruptedException(tcp+"block size error:"+kb.size);
|
|
||||||
}
|
|
||||||
kb.data = new byte[kb.size];
|
|
||||||
in.readFully(kb.data);
|
|
||||||
}else if(kb.number==0){
|
|
||||||
kb.time=in.readLong();
|
|
||||||
}else if(kb.number==Long.MIN_VALUE) {
|
|
||||||
kb.time=in.readLong();
|
|
||||||
}else {
|
|
||||||
kb.time=in.readLong();
|
|
||||||
//tcp.nextRTT(System.nanoTime()-kb.time);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
System.out.println(tcp.getTunnel().getName()+" RECEIVE:" + kb);
|
|
||||||
return kb;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void closeRemote() {
|
|
||||||
closeremote = true;
|
|
||||||
outputcache.clear();
|
|
||||||
}
|
|
||||||
public void closeLocal() {
|
|
||||||
closelocal = true;
|
|
||||||
inputcache.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void waitForRemote() {
|
|
||||||
while(outputcache.size()>0) {
|
|
||||||
try {
|
|
||||||
Thread.sleep(1);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public void waitForLocal() {
|
|
||||||
while(inputcache.size()>0) {
|
|
||||||
try {
|
|
||||||
Thread.sleep(1);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,14 +18,15 @@ import org.kne.cloud.network.mport.IPPort;
|
|||||||
import org.kne.cloud.network.mport.ServiceElement;
|
import org.kne.cloud.network.mport.ServiceElement;
|
||||||
|
|
||||||
public class KLALBServer {
|
public class KLALBServer {
|
||||||
|
|
||||||
WeakHashMap<UUID, IOThreadManager> whm=new WeakHashMap<>();
|
WeakHashMap<UUID, IOThreadManager> whm=new WeakHashMap<>();
|
||||||
public KLALBServer(int port, Map<String,ServiceElement> services,List<Tunnel> tunnels) throws IOException {
|
public KLALBServer(int port, Map<String,ServiceElement> services,List<Tunnel> tunnels) throws IOException {
|
||||||
TCPListener tcpl=new TCPListener(port);
|
TCPListener tcpl=new TCPListener(port);
|
||||||
tcpl.setCon((s)->{
|
tcpl.setCon((s)->{
|
||||||
TCPConnection tcc=null;
|
RemoteTCPConnection tcc=null;
|
||||||
try {
|
try {
|
||||||
//s.setSoTimeout(10000);
|
//s.setSoTimeout(10000);
|
||||||
tcc=new TCPConnection(null,s);
|
tcc=new RemoteTCPConnection(null,s);
|
||||||
DataInputStream din=tcc.getDin();
|
DataInputStream din=tcc.getDin();
|
||||||
int val=din.readShort()&0xffff;
|
int val=din.readShort()&0xffff;
|
||||||
if(val!=59649) {
|
if(val!=59649) {
|
||||||
@@ -52,16 +53,6 @@ public class KLALBServer {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String lip=din.readUTF();
|
|
||||||
int lport=din.readInt();
|
|
||||||
String lname=din.readUTF();
|
|
||||||
ServiceElement eas=services.get(lname);
|
|
||||||
System.out.println(eas);
|
|
||||||
|
|
||||||
if(eas==null||(!eas.ipport.equals(new IPPort(lip, lport)))){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String name = din.readUTF();
|
String name = din.readUTF();
|
||||||
String ip = din.readUTF();
|
String ip = din.readUTF();
|
||||||
int portx=din.readInt();
|
int portx=din.readInt();
|
||||||
@@ -69,28 +60,16 @@ public class KLALBServer {
|
|||||||
tcc.setTunnel(tll);
|
tcc.setTunnel(tll);
|
||||||
|
|
||||||
UUID uid=new UUID(din.readLong(),din.readLong());
|
UUID uid=new UUID(din.readLong(),din.readLong());
|
||||||
|
|
||||||
System.out.println(new IPPort((InetSocketAddress)s.getRemoteSocketAddress())+"->"+tll.getIpport()+"->"+eas.ipport);
|
|
||||||
IOThreadManager nx = null;
|
IOThreadManager nx = null;
|
||||||
|
synchronized (tcpl) {
|
||||||
if(whm.containsKey(uid)) {
|
if(whm.containsKey(uid)) {
|
||||||
nx=whm.get(uid);
|
nx=whm.get(uid);
|
||||||
}else {
|
}else {
|
||||||
nx=new IOThreadManager();
|
nx=new IOThreadManager();
|
||||||
Socket soc=new Socket(eas.ipport.getIp(),eas.ipport.getPort());
|
|
||||||
nx.setLocal(new TCPConnection(null, soc));
|
|
||||||
nx.startLocal();
|
|
||||||
whm.put(uid, nx);
|
whm.put(uid, nx);
|
||||||
|
|
||||||
}
|
}
|
||||||
nx.handleSocket(tcc);
|
|
||||||
int n=nx.getTcps().size();
|
|
||||||
System.out.println(nx.getTcps());
|
|
||||||
if(n<=0) {
|
|
||||||
nx.closeLocal();
|
|
||||||
System.out.println("连接已关闭");
|
|
||||||
}
|
}
|
||||||
}catch(ConnectException e) {
|
nx.handleRemote(tcc);
|
||||||
System.out.println("连接本地服务失败,请检查你的服务程序");
|
|
||||||
}catch(IOException e) {
|
}catch(IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}finally {
|
}finally {
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class LocalTCPConnection extends TCPConnection {
|
||||||
|
private UUID cuid;
|
||||||
|
public LocalTCPConnection(Socket s) throws IOException {
|
||||||
|
super(s);
|
||||||
|
cuid=UUID.randomUUID();
|
||||||
|
}
|
||||||
|
public LocalTCPConnection(Socket s,UUID uid) throws IOException {
|
||||||
|
super(s);
|
||||||
|
cuid=uid;
|
||||||
|
}
|
||||||
|
public UUID getCuid() {
|
||||||
|
return cuid;
|
||||||
|
}
|
||||||
|
public void setCuid(UUID cuid) {
|
||||||
|
this.cuid = cuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.BlockingDeque;
|
||||||
|
import java.util.concurrent.LinkedBlockingDeque;
|
||||||
|
|
||||||
|
import org.kne.cloud.network.mport.IPPort;
|
||||||
|
|
||||||
|
public class RemoteTCPConnection extends TCPConnection {
|
||||||
|
|
||||||
|
public RemoteTCPConnection(Tunnel t) throws UnknownHostException, IOException {
|
||||||
|
this(t,t.connectClientSocket());
|
||||||
|
}
|
||||||
|
public RemoteTCPConnection(Tunnel t,Socket s) throws UnknownHostException, IOException {
|
||||||
|
super(s);
|
||||||
|
this.tunnel=t;
|
||||||
|
s.setSoTimeout(Consts.SO_TIMEOUT);
|
||||||
|
}
|
||||||
|
private long delay=-1;
|
||||||
|
private Tunnel tunnel;
|
||||||
|
public Tunnel getTunnel() {
|
||||||
|
return tunnel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTunnel(Tunnel tunnel) {
|
||||||
|
this.tunnel = tunnel;
|
||||||
|
}
|
||||||
|
public long getDelay() {
|
||||||
|
return delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDelay(long delay) {
|
||||||
|
this.delay = delay;
|
||||||
|
if(tunnel!=null) {
|
||||||
|
tunnel.setDelay(delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public void sendBlock(KLALBBlock data) throws IOException {
|
||||||
|
dout.writeLong(data.sn);
|
||||||
|
dout.writeLong(data.cuid.getMostSignificantBits());
|
||||||
|
dout.writeLong(data.cuid.getLeastSignificantBits());
|
||||||
|
dout.writeLong(data.number);
|
||||||
|
if(data.number>0) {
|
||||||
|
dout.writeInt(data.data.length);
|
||||||
|
dout.write(data.data);
|
||||||
|
}else if(data.number==0) {
|
||||||
|
dout.write(data.command);
|
||||||
|
switch(data.command) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
dout.writeLong(data.pingtime);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
dout.writeUTF(data.lservice);
|
||||||
|
dout.writeUTF(data.lipport.toString());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dout.flush();
|
||||||
|
|
||||||
|
System.out.println("SEND:"+data);
|
||||||
|
}
|
||||||
|
public KLALBBlock receiveBlock() throws IOException {
|
||||||
|
KLALBBlock klb=new KLALBBlock();
|
||||||
|
klb.sn=din.readLong();
|
||||||
|
klb.cuid=new UUID(din.readLong(), din.readLong());
|
||||||
|
klb.number=din.readLong();
|
||||||
|
if(klb.number>0) {
|
||||||
|
int size=din.readInt();
|
||||||
|
byte[]d=new byte[size];
|
||||||
|
din.readFully(d);
|
||||||
|
klb.data=d;
|
||||||
|
}else if(klb.number==0) {
|
||||||
|
klb.command=din.read();
|
||||||
|
switch(klb.command) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
klb.pingtime=din.readLong();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
klb.lservice=din.readUTF();
|
||||||
|
klb.lipport=new IPPort(din.readUTF());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("RECEIVE:"+klb);
|
||||||
|
return klb;
|
||||||
|
}
|
||||||
|
|
||||||
|
private volatile long time=System.nanoTime();
|
||||||
|
public boolean checkPingTime() {
|
||||||
|
long cu=System.nanoTime();
|
||||||
|
if(cu-time>Consts.PINGTIMENS) {
|
||||||
|
time=cu;
|
||||||
|
return true;
|
||||||
|
}else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private BlockingDeque<KLALBBlock>sendDeque=new LinkedBlockingDeque<>();
|
||||||
|
public BlockingDeque<KLALBBlock> getSendDeque() {
|
||||||
|
return sendDeque;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,28 +8,16 @@ import java.io.IOException;
|
|||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
|
import java.util.zip.GZIPInputStream;
|
||||||
|
import java.util.zip.GZIPOutputStream;
|
||||||
|
|
||||||
public class TCPConnection {
|
public class TCPConnection {
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "TCPConnection [tunnel=" + tunnel + ", connect=" + connect + ", delay=" + delay + "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
private Tunnel tunnel;
|
|
||||||
private Socket connect;
|
private Socket connect;
|
||||||
private DataInputStream din;
|
protected DataInputStream din;
|
||||||
|
protected DataOutputStream dout;
|
||||||
public Tunnel getTunnel() {
|
|
||||||
return tunnel;
|
|
||||||
}
|
|
||||||
|
|
||||||
private DataOutputStream dout;
|
|
||||||
private long delay=-1;
|
|
||||||
|
|
||||||
/*public Socket getConnect() {
|
|
||||||
return connect;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
public DataInputStream getDin() {
|
public DataInputStream getDin() {
|
||||||
return din;
|
return din;
|
||||||
@@ -61,44 +49,19 @@ public class TCPConnection {
|
|||||||
// TODO 自动生成的 catch 块
|
// TODO 自动生成的 catch 块
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
if(tunnel!=null&&connect!=null)
|
|
||||||
tunnel.getCCount().decrementAndGet();
|
|
||||||
connect = null;
|
connect = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getDelay() {
|
public TCPConnection( Socket soc) throws IOException {
|
||||||
return delay;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDelay(long delay) {
|
|
||||||
this.delay = delay;
|
|
||||||
if(tunnel!=null) {
|
|
||||||
tunnel.setDelay(delay);
|
|
||||||
}
|
|
||||||
if(connect!=null) {
|
|
||||||
try {
|
|
||||||
connect.setSoTimeout(10000);
|
|
||||||
} catch (SocketException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTunnel(Tunnel tunnel) {
|
|
||||||
this.tunnel = tunnel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TCPConnection(Tunnel t) throws UnknownHostException, IOException {
|
|
||||||
this(t, t.connectClientSocket());
|
|
||||||
}
|
|
||||||
public TCPConnection(Tunnel t, Socket soc) throws IOException {
|
|
||||||
connect = soc;
|
connect = soc;
|
||||||
tunnel = t;
|
initIO();
|
||||||
if(t!=null) {
|
}
|
||||||
t.getCCount().incrementAndGet();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
protected void initIO() throws IOException {
|
||||||
|
dout = new DataOutputStream( connect.getOutputStream());
|
||||||
din = new DataInputStream(connect.getInputStream());
|
din = new DataInputStream(connect.getInputStream());
|
||||||
dout = new DataOutputStream(connect.getOutputStream());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isOpen() {
|
public boolean isOpen() {
|
||||||
@@ -107,24 +70,6 @@ public class TCPConnection {
|
|||||||
}
|
}
|
||||||
return !connect.isClosed();
|
return !connect.isClosed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private volatile long time=System.nanoTime();
|
|
||||||
public boolean checkPingTime() {
|
|
||||||
long cu=System.nanoTime();
|
|
||||||
if(cu-time>Consts.PINGTIMENS) {
|
|
||||||
time=cu;
|
|
||||||
return true;
|
|
||||||
}else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private volatile long RTT=10000000;
|
|
||||||
public void nextRTT(long NRTT) {
|
|
||||||
RTT=(long) ((1.0-Consts.A)*RTT+Consts.A*NRTT);
|
|
||||||
System.out.println(RTT);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ public class Tunnel {
|
|||||||
}
|
}
|
||||||
public Socket connectClientSocket() throws UnknownHostException, IOException {
|
public Socket connectClientSocket() throws UnknownHostException, IOException {
|
||||||
Socket socket=new Socket();
|
Socket socket=new Socket();
|
||||||
socket.connect(ipport.getSocketAddress(), 5000);
|
socket.connect(ipport.getSocketAddress(), 10000);
|
||||||
return socket;
|
return socket;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,5 +109,4 @@ public class Tunnel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,478 @@
|
|||||||
|
package org.kne.ui;
|
||||||
|
|
||||||
|
import java.awt.AWTEvent;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Container;
|
||||||
|
import java.awt.Cursor;
|
||||||
|
import java.awt.Point;
|
||||||
|
import java.awt.Toolkit;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.awt.event.MouseListener;
|
||||||
|
import java.awt.event.MouseMotionListener;
|
||||||
|
import java.awt.event.WindowEvent;
|
||||||
|
import java.awt.event.WindowListener;
|
||||||
|
|
||||||
|
import javax.swing.JFrame;
|
||||||
|
import javax.swing.SpringLayout;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.ImageIcon;
|
||||||
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import java.awt.Font;
|
||||||
|
import java.awt.Image;
|
||||||
|
|
||||||
|
import javax.swing.SwingConstants;
|
||||||
|
import java.awt.BorderLayout;
|
||||||
|
|
||||||
|
public class XFrame extends JFrame {
|
||||||
|
MouseListener lsr=new MouseListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseReleased(MouseEvent e) {
|
||||||
|
// TODO 自动生成的方法存根
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
if(e.getButton()==MouseEvent.BUTTON1) {
|
||||||
|
delta.x = e.getXOnScreen()-XFrame.this.getX();
|
||||||
|
delta.y = e.getYOnScreen()-XFrame.this.getY();
|
||||||
|
delta0.x = e.getXOnScreen()-(XFrame.this.getX()+XFrame.this.getWidth());
|
||||||
|
delta0.y = e.getYOnScreen()-(XFrame.this.getY()+XFrame.this.getHeight());
|
||||||
|
total.x=XFrame.this.getWidth()+XFrame.this.getX();
|
||||||
|
total.y=XFrame.this.getHeight()+XFrame.this.getY();
|
||||||
|
xb=e.getY()<=8;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseExited(MouseEvent e) {
|
||||||
|
// TODO 自动生成的方法存根
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseEntered(MouseEvent e) {
|
||||||
|
// TODO 自动生成的方法存根
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseClicked(MouseEvent e) {
|
||||||
|
// TODO 自动生成的方法存根
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Container getContentPane() {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Color invisible=new Color(255,255,255, 1);
|
||||||
|
private JPanel titlepanel;
|
||||||
|
private Point delta = new Point();
|
||||||
|
private Point delta0 = new Point();
|
||||||
|
private Point total = new Point();
|
||||||
|
private boolean xb;
|
||||||
|
private int state=0;
|
||||||
|
|
||||||
|
private JPanel content;
|
||||||
|
private JLabel titlelabel;
|
||||||
|
private JLabel iconi;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setIconImage(Image image) {
|
||||||
|
iconi.setIcon(new ImageIcon(image.getScaledInstance(27,27, Image.SCALE_SMOOTH)));
|
||||||
|
super.setIconImage(image);
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
public void setTitleColor(Color c) {
|
||||||
|
titlepanel.setBackground(c);
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
public Color getTitleColor() {
|
||||||
|
return titlepanel.getBackground();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTitle(String title) {
|
||||||
|
titlelabel.setText(title);
|
||||||
|
super.setTitle(title);
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public String getTitle() {
|
||||||
|
return super.getTitle();
|
||||||
|
}
|
||||||
|
|
||||||
|
public XFrame() {
|
||||||
|
setUndecorated(true);
|
||||||
|
|
||||||
|
super.setBackground(new Color(255, 255, 255, 0));
|
||||||
|
Container contentPane = super.getContentPane();
|
||||||
|
contentPane.setBackground(new Color(255, 255, 255, 0));
|
||||||
|
SpringLayout springLayout = new SpringLayout();
|
||||||
|
contentPane.setLayout(springLayout);
|
||||||
|
|
||||||
|
titlepanel = new JPanel();
|
||||||
|
//titlepanel.setOpaque(false);
|
||||||
|
titlepanel.setBorder(null);
|
||||||
|
springLayout.putConstraint(SpringLayout.WEST, titlepanel, 8, SpringLayout.WEST, contentPane);
|
||||||
|
springLayout.putConstraint(SpringLayout.SOUTH, titlepanel, 31, SpringLayout.NORTH, contentPane);
|
||||||
|
springLayout.putConstraint(SpringLayout.EAST, titlepanel, -8, SpringLayout.EAST, contentPane);
|
||||||
|
springLayout.putConstraint(SpringLayout.NORTH, titlepanel, 0, SpringLayout.NORTH, contentPane);
|
||||||
|
contentPane.add(titlepanel);
|
||||||
|
titlepanel.addMouseListener(lsr);
|
||||||
|
titlepanel.addMouseMotionListener(new MouseMotionListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseMoved(MouseEvent e) {
|
||||||
|
if(e.getY()<=8) {
|
||||||
|
titlepanel.setCursor(Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR));
|
||||||
|
}else {
|
||||||
|
titlepanel.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseDragged(MouseEvent e) {
|
||||||
|
Point p=e.getLocationOnScreen();
|
||||||
|
if(xb) {
|
||||||
|
XFrame.this.setLocation(XFrame.this.getX(),p.y-delta.y);
|
||||||
|
XFrame.this.setSize(XFrame.this.getWidth(), total.y-(p.y-delta.y));
|
||||||
|
}else {
|
||||||
|
XFrame.this.setLocation(p.x-delta.x,p.y-delta.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
JPanel lu = new JPanel();
|
||||||
|
springLayout.putConstraint(SpringLayout.NORTH, lu, 0, SpringLayout.NORTH, contentPane);
|
||||||
|
springLayout.putConstraint(SpringLayout.WEST, lu, 0, SpringLayout.WEST, contentPane);
|
||||||
|
springLayout.putConstraint(SpringLayout.SOUTH, lu, 8, SpringLayout.NORTH, contentPane);
|
||||||
|
springLayout.putConstraint(SpringLayout.EAST, lu, 8, SpringLayout.WEST, contentPane);
|
||||||
|
lu.setBackground(invisible);
|
||||||
|
lu.addMouseListener(lsr);
|
||||||
|
lu.setCursor(Cursor.getPredefinedCursor(Cursor.NW_RESIZE_CURSOR));
|
||||||
|
lu.addMouseMotionListener(new MouseMotionListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseMoved(MouseEvent e) {
|
||||||
|
// TODO 自动生成的方法存根
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseDragged(MouseEvent e) {
|
||||||
|
Point p=e.getLocationOnScreen();
|
||||||
|
XFrame.this.setLocation(p.x-delta.x,p.y-delta.y);
|
||||||
|
XFrame.this.setSize( total.x-(p.x-delta.x),total.y-(p.y-delta.y));
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
contentPane.add(lu);
|
||||||
|
|
||||||
|
JPanel ru = new JPanel();
|
||||||
|
springLayout.putConstraint(SpringLayout.NORTH, ru, 0, SpringLayout.NORTH, contentPane);
|
||||||
|
springLayout.putConstraint(SpringLayout.WEST, ru, -8, SpringLayout.EAST, contentPane);
|
||||||
|
springLayout.putConstraint(SpringLayout.SOUTH, ru, 8, SpringLayout.NORTH,contentPane);
|
||||||
|
springLayout.putConstraint(SpringLayout.EAST, ru, 0, SpringLayout.EAST, contentPane);
|
||||||
|
ru.setBackground(invisible);
|
||||||
|
ru.addMouseListener(lsr);
|
||||||
|
ru.setCursor(Cursor.getPredefinedCursor(Cursor.NE_RESIZE_CURSOR));
|
||||||
|
ru.addMouseMotionListener(new MouseMotionListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseMoved(MouseEvent e) {
|
||||||
|
// TODO 自动生成的方法存根
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseDragged(MouseEvent e) {
|
||||||
|
Point p=e.getLocationOnScreen();
|
||||||
|
XFrame.this.setLocation(XFrame.this.getX(),p.y-delta.y);
|
||||||
|
XFrame.this.setSize(p.x+delta0.x-XFrame.this.getX(), total.y-(p.y-delta.y));
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
contentPane.add(ru);
|
||||||
|
|
||||||
|
JPanel ld = new JPanel();
|
||||||
|
springLayout.putConstraint(SpringLayout.NORTH, ld, -8, SpringLayout.SOUTH, contentPane);
|
||||||
|
springLayout.putConstraint(SpringLayout.WEST, ld, 0, SpringLayout.WEST, contentPane);
|
||||||
|
springLayout.putConstraint(SpringLayout.SOUTH, ld, 0, SpringLayout.SOUTH, contentPane);
|
||||||
|
springLayout.putConstraint(SpringLayout.EAST, ld, 8, SpringLayout.WEST, contentPane);
|
||||||
|
ld.setBackground(invisible);
|
||||||
|
ld.addMouseListener(lsr);
|
||||||
|
ld.setCursor(Cursor.getPredefinedCursor(Cursor.SW_RESIZE_CURSOR));
|
||||||
|
ld.addMouseMotionListener(new MouseMotionListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseMoved(MouseEvent e) {
|
||||||
|
// TODO 自动生成的方法存根
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseDragged(MouseEvent e) {
|
||||||
|
Point p=e.getLocationOnScreen();
|
||||||
|
XFrame.this.setLocation(p.x-delta.x,XFrame.this.getY());
|
||||||
|
XFrame.this.setSize( total.x-(p.x-delta.x),p.y+delta0.y-XFrame.this.getY());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
contentPane.add(ld);
|
||||||
|
|
||||||
|
JPanel rd = new JPanel();
|
||||||
|
springLayout.putConstraint(SpringLayout.NORTH, rd, -8, SpringLayout.SOUTH, contentPane);
|
||||||
|
springLayout.putConstraint(SpringLayout.WEST, rd, -8, SpringLayout.EAST, contentPane);
|
||||||
|
springLayout.putConstraint(SpringLayout.SOUTH, rd, 0, SpringLayout.SOUTH, contentPane);
|
||||||
|
springLayout.putConstraint(SpringLayout.EAST, rd, 0, SpringLayout.EAST, contentPane);
|
||||||
|
rd.setBackground(invisible);
|
||||||
|
rd.addMouseListener(lsr);
|
||||||
|
rd.setCursor(Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR));
|
||||||
|
rd.addMouseMotionListener(new MouseMotionListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseMoved(MouseEvent e) {
|
||||||
|
// TODO 自动生成的方法存根
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseDragged(MouseEvent e) {
|
||||||
|
Point p=e.getLocationOnScreen();
|
||||||
|
XFrame.this.setSize(p.x+delta0.x-XFrame.this.getX(), p.y+delta0.y-XFrame.this.getY());
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
contentPane.add(rd);
|
||||||
|
|
||||||
|
JPanel l = new JPanel();
|
||||||
|
springLayout.putConstraint(SpringLayout.NORTH, l, 0, SpringLayout.SOUTH, lu);
|
||||||
|
springLayout.putConstraint(SpringLayout.WEST, l, 0, SpringLayout.WEST, contentPane);
|
||||||
|
springLayout.putConstraint(SpringLayout.SOUTH, l, 0, SpringLayout.NORTH, ld);
|
||||||
|
springLayout.putConstraint(SpringLayout.EAST, l, 8, SpringLayout.WEST, contentPane);
|
||||||
|
l.setBackground(invisible);
|
||||||
|
l.addMouseListener(lsr);
|
||||||
|
l.setCursor(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR));
|
||||||
|
l.addMouseMotionListener(new MouseMotionListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseMoved(MouseEvent e) {
|
||||||
|
// TODO 自动生成的方法存根
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseDragged(MouseEvent e) {
|
||||||
|
Point p=e.getLocationOnScreen();
|
||||||
|
XFrame.this.setLocation(p.x-delta.x,XFrame.this.getY());
|
||||||
|
XFrame.this.setSize( total.x-(p.x-delta.x),XFrame.this.getHeight());
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
contentPane.add(l);
|
||||||
|
|
||||||
|
JPanel r = new JPanel();
|
||||||
|
springLayout.putConstraint(SpringLayout.NORTH, r, 0, SpringLayout.SOUTH, ru);
|
||||||
|
springLayout.putConstraint(SpringLayout.WEST, r, -8, SpringLayout.EAST,contentPane);
|
||||||
|
springLayout.putConstraint(SpringLayout.SOUTH, r, 0, SpringLayout.NORTH, rd);
|
||||||
|
springLayout.putConstraint(SpringLayout.EAST, r, 0, SpringLayout.EAST, contentPane);
|
||||||
|
r.setBackground(invisible);
|
||||||
|
r.addMouseListener(lsr);
|
||||||
|
r.setCursor(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR));
|
||||||
|
r.addMouseMotionListener(new MouseMotionListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseMoved(MouseEvent e) {
|
||||||
|
// TODO 自动生成的方法存根
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseDragged(MouseEvent e) {
|
||||||
|
Point p=e.getLocationOnScreen();
|
||||||
|
XFrame.this.setSize(p.x+delta0.x-XFrame.this.getX(), XFrame.this.getHeight());
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
contentPane.add(r);
|
||||||
|
|
||||||
|
JPanel d = new JPanel();
|
||||||
|
springLayout.putConstraint(SpringLayout.NORTH, d, -8, SpringLayout.SOUTH, contentPane);
|
||||||
|
springLayout.putConstraint(SpringLayout.WEST, d, 0, SpringLayout.EAST, ld);
|
||||||
|
springLayout.putConstraint(SpringLayout.SOUTH, d, 0, SpringLayout.SOUTH, contentPane);
|
||||||
|
springLayout.putConstraint(SpringLayout.EAST, d, 0, SpringLayout.WEST, rd);
|
||||||
|
d.setBackground(invisible);
|
||||||
|
d.addMouseListener(lsr);
|
||||||
|
d.setCursor(Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR));
|
||||||
|
d.addMouseMotionListener(new MouseMotionListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseMoved(MouseEvent e) {
|
||||||
|
// TODO 自动生成的方法存根
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseDragged(MouseEvent e) {
|
||||||
|
Point p=e.getLocationOnScreen();
|
||||||
|
XFrame.this.setSize(XFrame.this.getWidth(), p.y+delta0.y-XFrame.this.getY());
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
contentPane.add(d);
|
||||||
|
|
||||||
|
content = new JPanel();
|
||||||
|
content.setBorder(null);
|
||||||
|
springLayout.putConstraint(SpringLayout.NORTH, content, 0, SpringLayout.SOUTH, titlepanel);
|
||||||
|
SpringLayout sl_titlepanel = new SpringLayout();
|
||||||
|
titlepanel.setLayout(sl_titlepanel);
|
||||||
|
|
||||||
|
JButton close = new JButton("");
|
||||||
|
close.setBackground(Color.WHITE);
|
||||||
|
close.setForeground(Color.WHITE);
|
||||||
|
close.setIcon(new ImageIcon(XFrame.class.getResource("/assets/close.png")));
|
||||||
|
sl_titlepanel.putConstraint(SpringLayout.NORTH, close, 0, SpringLayout.NORTH, titlepanel);
|
||||||
|
sl_titlepanel.putConstraint(SpringLayout.WEST, close, -46, SpringLayout.EAST, titlepanel);
|
||||||
|
sl_titlepanel.putConstraint(SpringLayout.SOUTH, close, 0, SpringLayout.SOUTH, titlepanel);
|
||||||
|
sl_titlepanel.putConstraint(SpringLayout.EAST, close, 0, SpringLayout.EAST, titlepanel);
|
||||||
|
close.setBorderPainted(false);
|
||||||
|
close.setContentAreaFilled(false);
|
||||||
|
close.setFocusPainted(false);
|
||||||
|
close.addActionListener(new ActionListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
XFrame.super.processWindowEvent(new WindowEvent(XFrame.this, WindowEvent.WINDOW_CLOSING));
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
titlepanel.add(close);
|
||||||
|
iconi = new JLabel("");
|
||||||
|
iconi.setHorizontalAlignment(SwingConstants.CENTER);
|
||||||
|
sl_titlepanel.putConstraint(SpringLayout.NORTH, iconi, 0, SpringLayout.NORTH, titlepanel);
|
||||||
|
sl_titlepanel.putConstraint(SpringLayout.WEST, iconi, 0, SpringLayout.WEST, titlepanel);
|
||||||
|
sl_titlepanel.putConstraint(SpringLayout.SOUTH, iconi, 0, SpringLayout.SOUTH, titlepanel);
|
||||||
|
sl_titlepanel.putConstraint(SpringLayout.EAST, iconi, 31, SpringLayout.WEST, titlepanel);
|
||||||
|
iconi.setOpaque(false);
|
||||||
|
iconi.setBackground(invisible);
|
||||||
|
titlepanel.add(iconi);
|
||||||
|
JButton maxium = new JButton("");
|
||||||
|
maxium.setForeground(Color.WHITE);
|
||||||
|
maxium.setBackground(Color.WHITE);
|
||||||
|
maxium.setIcon(new ImageIcon(XFrame.class.getResource("/assets/maxium.png")));
|
||||||
|
sl_titlepanel.putConstraint(SpringLayout.NORTH, maxium, 0, SpringLayout.NORTH, close);
|
||||||
|
sl_titlepanel.putConstraint(SpringLayout.WEST, maxium, -46, SpringLayout.WEST, close);
|
||||||
|
sl_titlepanel.putConstraint(SpringLayout.SOUTH, maxium, 0, SpringLayout.SOUTH, titlepanel);
|
||||||
|
sl_titlepanel.putConstraint(SpringLayout.EAST, maxium, 0, SpringLayout.WEST, close);
|
||||||
|
maxium.setBorderPainted(false);
|
||||||
|
maxium.setContentAreaFilled(false);
|
||||||
|
maxium.setFocusPainted(false);
|
||||||
|
maxium.addActionListener(new ActionListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
int s=XFrame.this.getExtendedState();
|
||||||
|
if(s==JFrame.NORMAL)
|
||||||
|
XFrame.this.setExtendedState(JFrame.MAXIMIZED_BOTH);
|
||||||
|
if(s==JFrame.MAXIMIZED_BOTH)
|
||||||
|
XFrame.this.setExtendedState(JFrame.NORMAL);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
titlepanel.add(maxium);
|
||||||
|
|
||||||
|
JButton minium = new JButton("");
|
||||||
|
minium.setForeground(Color.WHITE);
|
||||||
|
minium.setBackground(Color.WHITE);
|
||||||
|
minium.setIcon(new ImageIcon(XFrame.class.getResource("/assets/minium.png")));
|
||||||
|
sl_titlepanel.putConstraint(SpringLayout.NORTH, minium, 0, SpringLayout.NORTH, close);
|
||||||
|
sl_titlepanel.putConstraint(SpringLayout.WEST, minium, -46, SpringLayout.WEST, maxium);
|
||||||
|
sl_titlepanel.putConstraint(SpringLayout.SOUTH, minium, 0, SpringLayout.SOUTH, close);
|
||||||
|
sl_titlepanel.putConstraint(SpringLayout.EAST, minium, 0, SpringLayout.WEST, maxium);
|
||||||
|
minium.setContentAreaFilled(false);
|
||||||
|
minium.setBorderPainted(false);
|
||||||
|
minium.setFocusPainted(false);
|
||||||
|
//minium.setRolloverEnabled(false);
|
||||||
|
minium.addActionListener(new ActionListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
int s=XFrame.this.getExtendedState();
|
||||||
|
if(s!=JFrame.ICONIFIED) {
|
||||||
|
state=s;
|
||||||
|
XFrame.this.setExtendedState(JFrame.ICONIFIED);
|
||||||
|
} else {
|
||||||
|
XFrame.this.setExtendedState(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
titlepanel.add(minium);
|
||||||
|
|
||||||
|
titlelabel = new JLabel();
|
||||||
|
sl_titlepanel.putConstraint(SpringLayout.WEST, titlelabel, 31, SpringLayout.WEST, titlepanel);
|
||||||
|
sl_titlepanel.putConstraint(SpringLayout.EAST, titlelabel, -31, SpringLayout.EAST, titlepanel);
|
||||||
|
titlelabel.setFont(new Font("宋体", Font.PLAIN, 16));
|
||||||
|
sl_titlepanel.putConstraint(SpringLayout.NORTH, titlelabel, 0, SpringLayout.NORTH, titlepanel);
|
||||||
|
sl_titlepanel.putConstraint(SpringLayout.SOUTH, titlelabel, 0, SpringLayout.SOUTH, titlepanel);
|
||||||
|
titlelabel.setOpaque(false);
|
||||||
|
titlelabel.setBackground(invisible);
|
||||||
|
titlepanel.add(titlelabel);
|
||||||
|
springLayout.putConstraint(SpringLayout.WEST, content, 0, SpringLayout.EAST, l);
|
||||||
|
springLayout.putConstraint(SpringLayout.SOUTH, content, 0, SpringLayout.NORTH, d);
|
||||||
|
springLayout.putConstraint(SpringLayout.EAST, content, 0, SpringLayout.WEST, r);
|
||||||
|
contentPane.add(content);
|
||||||
|
content.setLayout(new BorderLayout(0, 0));
|
||||||
|
addWindowListener(new WindowListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowOpened(WindowEvent e) {
|
||||||
|
// TODO 自动生成的方法存根
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowIconified(WindowEvent e) {
|
||||||
|
// TODO 自动生成的方法存根
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowDeiconified(WindowEvent e) {
|
||||||
|
XFrame.this.setExtendedState(state);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowDeactivated(WindowEvent e) {
|
||||||
|
// TODO 自动生成的方法存根
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowClosing(WindowEvent e) {
|
||||||
|
// TODO 自动生成的方法存根
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowClosed(WindowEvent e) {
|
||||||
|
// TODO 自动生成的方法存根
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowActivated(WindowEvent e) {
|
||||||
|
// TODO 自动生成的方法存根
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user