TCP连接池功能

This commit is contained in:
Administrator
2022-12-11 17:27:03 +08:00
parent 35cccfde4b
commit 5d7324db0e
15 changed files with 948 additions and 619 deletions
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

+3 -1
View File
@@ -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;
}
@@ -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 List<TCPConnection>tcps=new Vector<>();
private KLALBCore klc = new KLALBCore(5000);
private boolean isopen = true;
private TCPConnection local;
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) {
});
Thread lr = ThreadTool.makeVThreadIfSupport("本地接收线程", () -> {
}catch(Exception e) {
up.interrupt();
});
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();
}
});
up.start();
down.start();
try {
down.join();
} catch (InterruptedException e) {
});
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 {
tcps.remove(s);
} finally {
klc.getRemotetcps().remove(tc);
}
}
public void closeRemote() {
open=false;
for (int i = 0; i < tcps.size(); i++) {
TCPConnection tll=tcps.get(i);
tll.close();
}
klc.closeRemote();
public void close() {
isopen = false;
}
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() {
return open;
return isopen;
}
}
+41 -33
View File
@@ -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;
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;
volatile long time=-1;
volatile TCPConnection connect;
public KLALBBlock(byte[] b, int size,long number) {
data=b;
this.size=size;
this.number=number;
}
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;
}
}
@@ -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<Tunnel> 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<Tunnel> 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();
@@ -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();
}
}
+127 -265
View File
@@ -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<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 static final UUID ZERO_UUID=new UUID(0,0);
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) {
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<KLALBBlock> 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<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;
}
}
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<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(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<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.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();
}
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 submitDataBlock(KLALBBlock kb) {
}
public void submitDataBlockNoDelay(KLALBBlock kb) {
synchronized (remotetcps) {
for (Iterator<RemoteTCPConnection> iterator = remotetcps.iterator(); iterator.hasNext();) {
RemoteTCPConnection rmt = (RemoteTCPConnection) iterator.next();
rmt.getSendDeque().addFirst(kb);
}
}
}
@@ -18,14 +18,15 @@ import org.kne.cloud.network.mport.IPPort;
import org.kne.cloud.network.mport.ServiceElement;
public class KLALBServer {
WeakHashMap<UUID, IOThreadManager> whm=new WeakHashMap<>();
public KLALBServer(int port, Map<String,ServiceElement> services,List<Tunnel> 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 {
@@ -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.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() {
@@ -109,22 +72,4 @@ public class TCPConnection {
}
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);
}
}
+1 -2
View File
@@ -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 {
}
}
+478
View File
@@ -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 自动生成的方法存根
}
});
}
}