From 5d7324db0e3d6021cdc50e78b177015bbd7a45d9 Mon Sep 17 00:00:00 2001 From: Administrator Date: Sun, 11 Dec 2022 17:27:03 +0800 Subject: [PATCH] =?UTF-8?q?TCP=E8=BF=9E=E6=8E=A5=E6=B1=A0=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/close.png | Bin 0 -> 3005 bytes src/assets/maxium.png | Bin 0 -> 2842 bytes src/assets/minium.png | Bin 0 -> 2813 bytes src/org/kne/cloud/network/klalb/Consts.java | 4 +- .../cloud/network/klalb/IOThreadManager.java | 199 +++----- .../kne/cloud/network/klalb/KLALBBlock.java | 80 +-- .../kne/cloud/network/klalb/KLALBClient.java | 146 ++---- .../cloud/network/klalb/KLALBClientGUI.java | 22 + .../kne/cloud/network/klalb/KLALBCore.java | 388 +++++--------- .../kne/cloud/network/klalb/KLALBServer.java | 31 +- .../network/klalb/LocalTCPConnection.java | 25 + .../network/klalb/RemoteTCPConnection.java | 110 ++++ .../cloud/network/klalb/TCPConnection.java | 81 +-- src/org/kne/cloud/network/klalb/Tunnel.java | 3 +- src/org/kne/ui/XFrame.java | 478 ++++++++++++++++++ 15 files changed, 948 insertions(+), 619 deletions(-) create mode 100644 src/assets/close.png create mode 100644 src/assets/maxium.png create mode 100644 src/assets/minium.png create mode 100644 src/org/kne/cloud/network/klalb/KLALBClientGUI.java create mode 100644 src/org/kne/cloud/network/klalb/LocalTCPConnection.java create mode 100644 src/org/kne/cloud/network/klalb/RemoteTCPConnection.java create mode 100644 src/org/kne/ui/XFrame.java diff --git a/src/assets/close.png b/src/assets/close.png new file mode 100644 index 0000000000000000000000000000000000000000..4aa652de6b244de707b3ba8d75d2180a812af169 GIT binary patch literal 3005 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 literal 0 HcmV?d00001 diff --git a/src/assets/minium.png b/src/assets/minium.png new file mode 100644 index 0000000000000000000000000000000000000000..41b38cd84d90f7fb0b0801779ecbfd1efe30f6c1 GIT binary patch literal 2813 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 P00000NkvXXu0mjf$Xr(? literal 0 HcmV?d00001 diff --git a/src/org/kne/cloud/network/klalb/Consts.java b/src/org/kne/cloud/network/klalb/Consts.java index a5e57c7..9a25c5a 100644 --- a/src/org/kne/cloud/network/klalb/Consts.java +++ b/src/org/kne/cloud/network/klalb/Consts.java @@ -1,7 +1,9 @@ package org.kne.cloud.network.klalb; public class Consts { - public static final int BLOCKSIZE=65536; + public static final int BLOCKSIZE=32768; public static final long PINGTIMENS=10000000000L; public static final double A = 0.125; + public static final int SO_TIMEOUT = 20000; + public static final long SN_KEEP = 60000000000L; } diff --git a/src/org/kne/cloud/network/klalb/IOThreadManager.java b/src/org/kne/cloud/network/klalb/IOThreadManager.java index 0d2d454..b665e54 100644 --- a/src/org/kne/cloud/network/klalb/IOThreadManager.java +++ b/src/org/kne/cloud/network/klalb/IOThreadManager.java @@ -4,149 +4,90 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.SocketException; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.UUID; import java.util.Vector; +import java.util.WeakHashMap; +import org.kne.cloud.network.mport.ServiceElement; import org.kne.cloud.network.mport.ThreadTool; public class IOThreadManager { - private KLALBCore klc=new KLALBCore(10000); - private Listtcps=new Vector<>(); - - - private TCPConnection local; - + private KLALBCore klc = new KLALBCore(5000); + private boolean isopen = true; - private volatile boolean open=true; - public void startLocal() { - - 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); + public void handleLocal(LocalTCPConnection tc, ServiceElement se,boolean syn) { + klc.getLocaltcps().add(tc); try { - Thread up=ThreadTool.makeVThreadIfSupport("远程发送线程",()->{ - try{ - while(true) { - if(s.getTunnel().getName().contains("Openfrp")) { - klc.sendDataBlockControlOnly(s); - }else { - klc.sendDataBlock(s); - } + if(syn) { + KLALBBlock sbk=new KLALBBlock(); + sbk.cuid=tc.getCuid(); + sbk.number=0; + sbk.command=2; + sbk.lservice=se.proc; + sbk.lipport=se.ipport; + klc.submitDataBlockNoDelay(sbk); } - }catch(InterruptedException s1) { + Thread ls = ThreadTool.makeVThreadIfSupport("本地发送线程", () -> { - }catch(Exception e) { - e.printStackTrace(); - } - }); - Thread down=ThreadTool.makeVThreadIfSupport("远程接收线程",()->{ - try{ - while(true) { - klc.receiveDataBlock(s); - } - }catch(InterruptedException s1) { - - }catch(Exception e) { - up.interrupt(); + }); + Thread lr = ThreadTool.makeVThreadIfSupport("本地接收线程", () -> { + + }); + ls.start(); + lr.start(); + ls.join(); + lr.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + klc.getLocaltcps().remove(tc); + } + } + + 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(); } - }); + }); + 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(); - down.start(); - 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 getTcps() { - return tcps; + public void close() { + isopen = false; } + public boolean isOpen() { - return open; + return isopen; } + } diff --git a/src/org/kne/cloud/network/klalb/KLALBBlock.java b/src/org/kne/cloud/network/klalb/KLALBBlock.java index 2124865..9aba7ac 100644 --- a/src/org/kne/cloud/network/klalb/KLALBBlock.java +++ b/src/org/kne/cloud/network/klalb/KLALBBlock.java @@ -2,50 +2,58 @@ package org.kne.cloud.network.klalb; import java.util.Arrays; import java.util.Objects; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicLong; + +import org.kne.cloud.network.mport.IPPort; public class KLALBBlock { - volatile byte[]data; - volatile int size; - volatile long number; - - - volatile long time=-1; - volatile TCPConnection connect; - public KLALBBlock(byte[] b, int size,long number) { - data=b; - this.size=size; - this.number=number; - } + private static AtomicLong sng=new AtomicLong(0); + + public long sn;//每个数据包的唯一编号 + public UUID cuid;//用于识别数据包的stream ID号 + public long number;//数据包的编号,用于排序 + public byte[]data;//数据内容 + public int command;//功能标记 0=PING 1=PONG 2=SYN 3=RST + public long pingtime;//PING计时器 + + public String lservice; + public IPPort lipport; + + + public KLALBBlock() { - // TODO 自动生成的构造函数存根 - } + sn=sng.getAndIncrement(); + } + + + @Override public String toString() { + StringBuilder sb=new StringBuilder(); + sb.append(cuid); + sb.append(' '); if(number>0) { - return "DATA"+number+":"+size; - }else if(number==0){ - return "PING"; - }else if(number==Long.MIN_VALUE){ - return "PONG"; + sb.append("DATA").append(number).append(':').append(data.length); + }else if(number<0) { + sb.append("ACK").append(-number); }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; - } - } diff --git a/src/org/kne/cloud/network/klalb/KLALBClient.java b/src/org/kne/cloud/network/klalb/KLALBClient.java index b26ed1e..295d133 100644 --- a/src/org/kne/cloud/network/klalb/KLALBClient.java +++ b/src/org/kne/cloud/network/klalb/KLALBClient.java @@ -4,6 +4,7 @@ import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.IOException; +import java.net.ConnectException; import java.net.MalformedURLException; import java.net.Socket; import java.net.URI; @@ -21,111 +22,68 @@ import org.kne.cloud.network.mport.ServiceElement; import org.kne.cloud.network.mport.ThreadTool; public class KLALBClient { - private static Object olock=new Object(); - static { - new Thread(()->{ - while(true) { - try { - Thread.sleep(10000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - synchronized(olock) { - olock.notifyAll(); - } - } - }).start(); - } - - + + UUID suid=UUID.randomUUID(); + IOThreadManager iom=new IOThreadManager(); private List tls=new ArrayList<>(); private TCPListener tcpl; 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 { tcpl=new TCPListener(port); tcpl.setCon((s)->{ - IOThreadManager kcp=new IOThreadManager(); - UUID uid=UUID.randomUUID(); + LocalTCPConnection tcc = null; + 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 { - kcp.setLocal(new TCPConnection(null, s)); - kcp.startLocal(); - runProtocol(kcp,uid); + tc=new RemoteTCPConnection(tll); + tc.getDout().writeShort(59649); + 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) { e.printStackTrace(); + }finally { + if(tc!=null) + tc.close(); } - - }); - - - tcpl.open(); + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }).start(); + } } public List getTls() { return tls; @@ -139,7 +97,7 @@ public class KLALBClient { IPPort u=new IPPort(ipport); TCPConnection tcpc=null; 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().write(0); tcpc.getDout().flush(); diff --git a/src/org/kne/cloud/network/klalb/KLALBClientGUI.java b/src/org/kne/cloud/network/klalb/KLALBClientGUI.java new file mode 100644 index 0000000..1df7101 --- /dev/null +++ b/src/org/kne/cloud/network/klalb/KLALBClientGUI.java @@ -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(); + } + +} diff --git a/src/org/kne/cloud/network/klalb/KLALBCore.java b/src/org/kne/cloud/network/klalb/KLALBCore.java index d38e6ea..c12fe47 100644 --- a/src/org/kne/cloud/network/klalb/KLALBCore.java +++ b/src/org/kne/cloud/network/klalb/KLALBCore.java @@ -13,9 +13,11 @@ import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Queue; import java.util.Set; import java.util.TreeMap; +import java.util.UUID; import java.util.Vector; import java.util.WeakHashMap; import java.util.concurrent.ArrayBlockingQueue; @@ -25,294 +27,154 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Predicate; import org.kne.cloud.network.mport.ThreadTool; public class KLALBCore { - private volatile long inputcount = 1; - private volatile long outputcount = 1; - private Set inputcache = Collections.synchronizedSet(new HashSet<>()); - private List outputcache = new Vector<>(); - - private BlockingQueue ackp=new LinkedBlockingQueue<>(); - private BlockingQueue ackq=new LinkedBlockingQueue<>(); - private volatile boolean inlocal=true; - - private volatile boolean closeremote = false; - private volatile boolean closelocal = false; - + private static final UUID ZERO_UUID=new UUID(0,0); private volatile int cacheblocks; + + + private List localtcps = new Vector<>(); + private List remotetcps = new Vector<>(); + private PredicateacceptSYN; + + + private volatile long rsntime=System.nanoTime(); + private Set rsns=Collections.synchronizedSet(new HashSet()); + 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 getAcceptSYN() { + return acceptSYN; + } + + public void setAcceptSYN(Predicate acceptSYN) { + this.acceptSYN = acceptSYN; + } + + public List getLocaltcps() { + return localtcps; + } + + public List getRemotetcps() { + return remotetcps; + } + public KLALBCore(int cachesize) { cacheblocks=cachesize; } - public void packDataBlock(byte[] b, int size) throws InterruptedException { - - if (closelocal) - throw new InterruptedException(); - while (!outputcache.isEmpty()&&(outputcount-outputcache.get(0).number>cacheblocks)) { - if (closelocal) - Thread.currentThread().interrupt(); + public void remoteSend(RemoteTCPConnection tc) throws InterruptedException, IOException { + for(;;) { + if(tc.checkPingTime()) { + KLALBBlock pdb=new KLALBBlock(); + pdb.cuid=ZERO_UUID; + pdb.number=0; + pdb.command=0; + pdb.pingtime=System.nanoTime(); + tc.sendBlock(pdb); + } + if(!tc.getSendDeque().isEmpty()) + break; Thread.sleep(1); } - outputcache.add(new KLALBBlock(b, size, outputcount++)); - + KLALBBlock k=tc.getSendDeque().poll(); + if(k!=null) { + tc.sendBlock(k); + } } - - public byte[] unpackDataBlock() throws InterruptedException { - inlocal=false; - try { - if (closelocal) - throw new InterruptedException(); - byte[] b = null; - while (true) { - synchronized (inputcache) { - Iterator klb = inputcache.iterator(); - while (klb.hasNext()) { - KLALBBlock klalbBlock = (KLALBBlock) klb.next(); - if (klalbBlock.number < inputcount) { - klb.remove(); - } else if (klalbBlock.number == inputcount) { - b = klalbBlock.data; - klb.remove(); - } + public void remoteReceive(RemoteTCPConnection tc) throws IOException { + KLALBBlock brc=null; + for(;;) { + brc=tc.receiveBlock(); + SN s=new SN(brc.sn); + synchronized (rsns) { + if(!rsns.contains(s)) { + rsns.add(s); + break; + } + } + } + synchronized (rsns) { + long ctime=System.nanoTime(); + if(ctime-rsntime>10000000000L) { + rsntime=ctime; + for (Iterator 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; } - } - - private void makeAck(KLALBBlock klalbBlock) { - KLALBBlock klb1=new KLALBBlock(null, 0, -klalbBlock.number); - klb1.time=klalbBlock.time; - ackq.add(klb1); - if(ackp.size()<100) { - KLALBBlock klb2=new KLALBBlock(null, 0, -klalbBlock.number); - klb2.time=klalbBlock.time; - ackp.add(klb2); - } - } - - - public void sendDataBlock(TCPConnection out) throws IOException, InterruptedException { - if (closeremote) - throw new InterruptedException(); - //BlockingQueue 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(brc.cuid.equals(ZERO_UUID)) { + if(brc.number==0) { + if(brc.command==0) { + KLALBBlock pdb=new KLALBBlock(); + pdb.cuid=ZERO_UUID; + pdb.number=0; + pdb.command=1; + pdb.pingtime=brc.pingtime; + tc.getSendDeque().addFirst(pdb); + }else if(brc.command==1) { + long cur=System.nanoTime(); + long delay=(cur-brc.pingtime)/2; + tc.setDelay(delay); } } - if (ks != null) { - send0(out, ks); - ks.time = System.nanoTime(); - }else { - Thread.sleep(1); - } - } - - if(out.checkPingTime()) { - send0(out, new KLALBBlock(null,0 , 0)); - } - } - - public void sendDataBlockControlOnly(TCPConnection out) throws IOException, InterruptedException { - if (closeremote) - throw new InterruptedException(); - //BlockingQueue 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 bq=acks.get(in); - if(bq==null) { - BlockingQueue 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.number==0) { + if(brc.command==0) { + }else if(brc.command==1) { + }else if(brc.command==2) { + if(acceptSYN==null||!acceptSYN.test(brc)) { + KLALBBlock rst=new KLALBBlock(); + rst.cuid=brc.cuid; + rst.number=0; + rst.command=3; + submitDataBlockNoDelay(rst); } - - inputcache.add(x); + }else if(brc.command==3) { } - 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; - }); } } - - 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(); + public void submitDataBlock(KLALBBlock kb) { - } - System.out.println(tcp.getTunnel().getName()+" SEND:" + kd); } - - private KLALBBlock receive0(TCPConnection tcp) throws IOException { - KLALBBlock kb = new KLALBBlock(); - DataInputStream in=tcp.getDin(); - synchronized (in) { - - 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(); + public void submitDataBlockNoDelay(KLALBBlock kb) { + synchronized (remotetcps) { + for (Iterator iterator = remotetcps.iterator(); iterator.hasNext();) { + RemoteTCPConnection rmt = (RemoteTCPConnection) iterator.next(); + rmt.getSendDeque().addFirst(kb); } } } diff --git a/src/org/kne/cloud/network/klalb/KLALBServer.java b/src/org/kne/cloud/network/klalb/KLALBServer.java index e4bcd2b..8f2d9a1 100644 --- a/src/org/kne/cloud/network/klalb/KLALBServer.java +++ b/src/org/kne/cloud/network/klalb/KLALBServer.java @@ -18,14 +18,15 @@ import org.kne.cloud.network.mport.IPPort; import org.kne.cloud.network.mport.ServiceElement; public class KLALBServer { + WeakHashMap whm=new WeakHashMap<>(); public KLALBServer(int port, Map services,List tunnels) throws IOException { TCPListener tcpl=new TCPListener(port); tcpl.setCon((s)->{ - TCPConnection tcc=null; + RemoteTCPConnection tcc=null; try { //s.setSoTimeout(10000); - tcc=new TCPConnection(null,s); + tcc=new RemoteTCPConnection(null,s); DataInputStream din=tcc.getDin(); int val=din.readShort()&0xffff; if(val!=59649) { @@ -52,16 +53,6 @@ public class KLALBServer { 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 ip = din.readUTF(); int portx=din.readInt(); @@ -69,28 +60,16 @@ public class KLALBServer { tcc.setTunnel(tll); UUID uid=new UUID(din.readLong(),din.readLong()); - - System.out.println(new IPPort((InetSocketAddress)s.getRemoteSocketAddress())+"->"+tll.getIpport()+"->"+eas.ipport); IOThreadManager nx = null; + synchronized (tcpl) { if(whm.containsKey(uid)) { nx=whm.get(uid); }else { 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); - } - nx.handleSocket(tcc); - int n=nx.getTcps().size(); - System.out.println(nx.getTcps()); - if(n<=0) { - nx.closeLocal(); - System.out.println("连接已关闭"); } - }catch(ConnectException e) { - System.out.println("连接本地服务失败,请检查你的服务程序"); + nx.handleRemote(tcc); }catch(IOException e) { e.printStackTrace(); }finally { diff --git a/src/org/kne/cloud/network/klalb/LocalTCPConnection.java b/src/org/kne/cloud/network/klalb/LocalTCPConnection.java new file mode 100644 index 0000000..7dd49c2 --- /dev/null +++ b/src/org/kne/cloud/network/klalb/LocalTCPConnection.java @@ -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; + } + +} diff --git a/src/org/kne/cloud/network/klalb/RemoteTCPConnection.java b/src/org/kne/cloud/network/klalb/RemoteTCPConnection.java new file mode 100644 index 0000000..6a041f1 --- /dev/null +++ b/src/org/kne/cloud/network/klalb/RemoteTCPConnection.java @@ -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 BlockingDequesendDeque=new LinkedBlockingDeque<>(); + public BlockingDeque getSendDeque() { + return sendDeque; + } +} diff --git a/src/org/kne/cloud/network/klalb/TCPConnection.java b/src/org/kne/cloud/network/klalb/TCPConnection.java index 4c97b5d..a97a05f 100644 --- a/src/org/kne/cloud/network/klalb/TCPConnection.java +++ b/src/org/kne/cloud/network/klalb/TCPConnection.java @@ -8,28 +8,16 @@ import java.io.IOException; import java.net.Socket; import java.net.SocketException; import java.net.UnknownHostException; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; public class TCPConnection { - @Override - public String toString() { - return "TCPConnection [tunnel=" + tunnel + ", connect=" + connect + ", delay=" + delay + "]"; - } - private Tunnel tunnel; + private Socket connect; - private DataInputStream din; - - public Tunnel getTunnel() { - return tunnel; - } - - private DataOutputStream dout; - private long delay=-1; - - /*public Socket getConnect() { - return connect; - }*/ + protected DataInputStream din; + protected DataOutputStream dout; public DataInputStream getDin() { return din; @@ -61,44 +49,19 @@ public class TCPConnection { // TODO 自动生成的 catch 块 e.printStackTrace(); } - if(tunnel!=null&&connect!=null) - tunnel.getCCount().decrementAndGet(); connect = null; } - public long getDelay() { - 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 { + public TCPConnection( Socket soc) throws IOException { connect = soc; - tunnel = t; - if(t!=null) { - t.getCCount().incrementAndGet(); - } + initIO(); + } + + + + protected void initIO() throws IOException { + dout = new DataOutputStream( connect.getOutputStream()); din = new DataInputStream(connect.getInputStream()); - dout = new DataOutputStream(connect.getOutputStream()); } public boolean isOpen() { @@ -107,24 +70,6 @@ public class TCPConnection { } 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); - } - } diff --git a/src/org/kne/cloud/network/klalb/Tunnel.java b/src/org/kne/cloud/network/klalb/Tunnel.java index 250f1d4..0003d64 100644 --- a/src/org/kne/cloud/network/klalb/Tunnel.java +++ b/src/org/kne/cloud/network/klalb/Tunnel.java @@ -76,7 +76,7 @@ public class Tunnel { } public Socket connectClientSocket() throws UnknownHostException, IOException { Socket socket=new Socket(); - socket.connect(ipport.getSocketAddress(), 5000); + socket.connect(ipport.getSocketAddress(), 10000); return socket; } @@ -109,5 +109,4 @@ public class Tunnel { } - } diff --git a/src/org/kne/ui/XFrame.java b/src/org/kne/ui/XFrame.java new file mode 100644 index 0000000..7caa7a4 --- /dev/null +++ b/src/org/kne/ui/XFrame.java @@ -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 自动生成的方法存根 + + } + }); + } +}