Compare commits

...
Author SHA1 Message Date
KNEMC 2dd62ec7c4 KLALB 3.6.0开发一半的状态 2026-07-06 17:16:33 +08:00
KNEMC c8b183da71 KLALB 3.6.0开发一半的状态 2026-07-06 17:03:27 +08:00
Administrator 620afef715 KLALB V3.6.0 写了一半 2026-02-27 08:32:03 +08:00
Administrator 816e672843 ADD License 2025-11-15 11:19:43 +08:00
Administrator 8842566ee2 KLALB V3.4 2025-11-15 11:08:16 +08:00
Administrator 306bfd36f7 UI改进 2025-08-08 17:13:27 +08:00
Administrator 7267aec1fd KLALB3.2 2025-04-24 10:16:38 +08:00
Administrator 6de65562be 优化代码,性能暴涨 2025-01-29 14:01:11 +08:00
Administrator e243203535 KLALB2.3 2024-08-18 17:47:11 +08:00
Administrator e4f4c77c19 UPDATE 2.2 2024-01-30 16:54:57 +08:00
392 changed files with 38741 additions and 4473 deletions
+24 -5
View File
@@ -1,14 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<classpath> <classpath>
<classpathentry kind="src" path="src"/> <classpathentry kind="src" path="src"/>
<classpathentry combineaccessrules="false" kind="src" path="/KNElib"/> <classpathentry kind="lib" path="lib/gson-2.1.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk-19"> <classpathentry kind="lib" path="lib/javassist.jar" sourcepath="C:/Users/ADMINI~1/AppData/Local/Temp/1/.org.sf.feeling.decompiler1686963856070/source/javassist-3.29.2-GA-sources.jar"/>
<classpathentry kind="lib" path="lib/ini4j.jar"/>
<classpathentry kind="lib" path="lib/JFreeChart1.5.2.jar"/>
<classpathentry kind="lib" path="lib/toml4j-0.7.1.jar"/>
<classpathentry kind="lib" path="lib/pcap4j-core-1.8.2.jar" sourcepath="C:/Users/ADMINI~1/AppData/Local/Temp/1/.org.sf.feeling.decompiler1725520274095/source/pcap4j-core-1.8.2-sources.jar"/>
<classpathentry kind="lib" path="lib/pcap4j-packetfactory-propertiesbased-1.8.2.jar"/>
<classpathentry kind="lib" path="lib/pcap4j-packetfactory-static-1.8.2.jar"/>
<classpathentry kind="lib" path="lib/pcap4j-sample-1.8.2.jar"/>
<classpathentry kind="lib" path="lib/slf4j-api-2.0.9.jar"/>
<classpathentry kind="lib" path="lib/slf4j-api-2.0.9-javadoc.jar"/>
<classpathentry kind="lib" path="lib/slf4j-api-2.0.9-sources.jar"/>
<classpathentry kind="lib" path="lib/slf4j-api-2.0.9-tests.jar"/>
<classpathentry kind="lib" path="lib/disruptor-4.0.0.jar" sourcepath="lib/disruptor-4.0.0-sources.jar"/>
<classpathentry kind="lib" path="lib/disruptor-4.0.0-javadoc.jar"/>
<classpathentry kind="lib" path="lib/disruptor-4.0.0-sources.jar"/>
<classpathentry kind="lib" path="lib/KNElib1.0.jar"/>
<classpathentry kind="lib" path="lib/KNEOptimize.jar"/>
<classpathentry kind="lib" path="lib/JavaTUN0.3.jar"/>
<classpathentry kind="lib" path="lib/uuid-creator-6.1.1.jar"/>
<classpathentry kind="lib" path="lib/jctools-core-4.0.6.jar"/>
<classpathentry kind="lib" path="lib/jctools-core-4.0.6-javadoc.jar"/>
<classpathentry kind="lib" path="lib/jctools-core-4.0.6-sources.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk-26.0.1">
<attributes> <attributes>
<attribute name="module" value="true"/> <attribute name="module" value="true"/>
</attributes> </attributes>
</classpathentry> </classpathentry>
<classpathentry kind="lib" path="lib/gson-2.1.jar"/>
<classpathentry kind="lib" path="lib/javassist.jar" sourcepath="C:/Users/ADMINI~1/AppData/Local/Temp/1/.org.sf.feeling.decompiler1686963856070/source/javassist-3.29.2-GA-sources.jar"/>
<classpathentry kind="lib" path="lib/ini4j.jar"/>
<classpathentry kind="output" path="bin"/> <classpathentry kind="output" path="bin"/>
</classpath> </classpath>
+10
View File
@@ -0,0 +1,10 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Ignored default folder with query files
/queries/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2">
<output url="file://$PROJECT_DIR$/classes" />
</component>
</project>
+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/KLALB.iml" filepath="$PROJECT_DIR$/KLALB.iml" />
</modules>
</component>
</project>
Generated
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>
+253
View File
@@ -0,0 +1,253 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="EclipseModuleManager">
<libelement value="jar://$MODULE_DIR$/lib/gson-2.1.jar!/" />
<libelement value="jar://$MODULE_DIR$/lib/javassist.jar!/" />
<libelement value="jar://$MODULE_DIR$/lib/ini4j.jar!/" />
<libelement value="jar://$MODULE_DIR$/lib/JFreeChart1.5.2.jar!/" />
<libelement value="jar://$MODULE_DIR$/lib/toml4j-0.7.1.jar!/" />
<libelement value="jar://$MODULE_DIR$/lib/pcap4j-core-1.8.2.jar!/" />
<libelement value="jar://$MODULE_DIR$/lib/pcap4j-packetfactory-propertiesbased-1.8.2.jar!/" />
<libelement value="jar://$MODULE_DIR$/lib/pcap4j-packetfactory-static-1.8.2.jar!/" />
<libelement value="jar://$MODULE_DIR$/lib/pcap4j-sample-1.8.2.jar!/" />
<libelement value="jar://$MODULE_DIR$/lib/slf4j-api-2.0.9.jar!/" />
<libelement value="jar://$MODULE_DIR$/lib/slf4j-api-2.0.9-javadoc.jar!/" />
<libelement value="jar://$MODULE_DIR$/lib/slf4j-api-2.0.9-sources.jar!/" />
<libelement value="jar://$MODULE_DIR$/lib/slf4j-api-2.0.9-tests.jar!/" />
<libelement value="jar://$MODULE_DIR$/lib/disruptor-4.0.0.jar!/" />
<libelement value="jar://$MODULE_DIR$/lib/disruptor-4.0.0-javadoc.jar!/" />
<libelement value="jar://$MODULE_DIR$/lib/disruptor-4.0.0-sources.jar!/" />
<libelement value="jar://$MODULE_DIR$/lib/KNElib1.0.jar!/" />
<libelement value="jar://$MODULE_DIR$/lib/KNEOptimize.jar!/" />
<libelement value="jar://$MODULE_DIR$/lib/JavaTUN0.3.jar!/" />
<libelement value="jar://$MODULE_DIR$/lib/uuid-creator-6.1.1.jar!/" />
<libelement value="jar://$MODULE_DIR$/lib/jctools-core-4.0.6.jar!/" />
<libelement value="jar://$MODULE_DIR$/lib/jctools-core-4.0.6-javadoc.jar!/" />
<libelement value="jar://$MODULE_DIR$/lib/jctools-core-4.0.6-sources.jar!/" />
<src_description expected_position="0">
<src_folder value="file://$MODULE_DIR$/src" expected_position="0" />
</src_description>
</component>
<component name="NewModuleRootManager">
<output url="file://$MODULE_DIR$/bin" />
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module-library">
<library name="gson-2.1.jar">
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/gson-2.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library name="javassist.jar">
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/javassist.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="file://$MODULE_DIR$/../../../../Users/ADMINI~1/AppData/Local/Temp/1/.org.sf.feeling.decompiler1686963856070/source/javassist-3.29.2-GA-sources.jar" />
</SOURCES>
</library>
</orderEntry>
<orderEntry type="module-library">
<library name="ini4j.jar">
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/ini4j.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library name="JFreeChart1.5.2.jar">
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/JFreeChart1.5.2.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library name="toml4j-0.7.1.jar">
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/toml4j-0.7.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library name="pcap4j-core-1.8.2.jar">
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/pcap4j-core-1.8.2.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="file://$MODULE_DIR$/../../../../Users/ADMINI~1/AppData/Local/Temp/1/.org.sf.feeling.decompiler1725520274095/source/pcap4j-core-1.8.2-sources.jar" />
</SOURCES>
</library>
</orderEntry>
<orderEntry type="module-library">
<library name="pcap4j-packetfactory-propertiesbased-1.8.2.jar">
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/pcap4j-packetfactory-propertiesbased-1.8.2.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library name="pcap4j-packetfactory-static-1.8.2.jar">
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/pcap4j-packetfactory-static-1.8.2.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library name="pcap4j-sample-1.8.2.jar">
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/pcap4j-sample-1.8.2.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library name="slf4j-api-2.0.9.jar">
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/slf4j-api-2.0.9.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library name="slf4j-api-2.0.9-javadoc.jar">
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/slf4j-api-2.0.9-javadoc.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library name="slf4j-api-2.0.9-sources.jar">
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/slf4j-api-2.0.9-sources.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library name="slf4j-api-2.0.9-tests.jar">
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/slf4j-api-2.0.9-tests.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library name="disruptor-4.0.0.jar">
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/disruptor-4.0.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$MODULE_DIR$/lib/disruptor-4.0.0-sources.jar!/" />
</SOURCES>
</library>
</orderEntry>
<orderEntry type="module-library">
<library name="disruptor-4.0.0-javadoc.jar">
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/disruptor-4.0.0-javadoc.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library name="disruptor-4.0.0-sources.jar">
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/disruptor-4.0.0-sources.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library name="KNElib1.0.jar">
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/KNElib1.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library name="KNEOptimize.jar">
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/KNEOptimize.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library name="JavaTUN0.3.jar">
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/JavaTUN0.3.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library name="uuid-creator-6.1.1.jar">
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/uuid-creator-6.1.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library name="jctools-core-4.0.6.jar">
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/jctools-core-4.0.6.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library name="jctools-core-4.0.6-javadoc.jar">
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/jctools-core-4.0.6-javadoc.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library name="jctools-core-4.0.6-sources.jar">
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/jctools-core-4.0.6-sources.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="jdk" jdkName="jdk-26.0.1" jdkType="JavaSDK" />
</component>
</module>
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+674 -427
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
+123
View File
@@ -0,0 +1,123 @@
[
{
"language": "ZH_CN",
"nogui": false,
"VirtualAddress": "2486:1:0:0:0:0:0:8888",
"VirtualASN": 2142606939373348329,
"DNS": [
"2486:1:0:0:0:0:0:8888"
],
"TCPListen": "0.0.0.0:4565",
"UDPListen": "{UDP}0.0.0.0:4572",
"VirtualSocketName": "KLALB_Stream",
"LineTable": [
"07f4acdef99b.ofalias.net:4565"
],
"ConnectLineTable": [
"home-ipv6.sliveridc1.cn:4565",
"home-ltipv6.sliveridc1.cn:4565",
"cn-gd-gz.sliveridc1.cn:4565"
],
"ntpServerTable": [
"{UDP}ntp1.aliyun.com:123",
"{UDP}ntp2.aliyun.com:123",
"{UDP}ntp3.aliyun.com:123",
"{UDP}ntp4.aliyun.com:123",
"{UDP}ntp5.aliyun.com:123",
"{UDP}ntp6.aliyun.com:123",
"{UDP}ntp7.aliyun.com:123",
"{UDP}ntp1.tencent.com:123",
"{UDP}ntp2.tencent.com:123",
"{UDP}ntp3.tencent.com:123",
"{UDP}ntp4.tencent.com:123",
"{UDP}ntp5.tencent.com:123",
"{UDP}time.google.com:123",
"{UDP}time.apple.com:123",
"{UDP}pool.ntp.org:123",
"{UDP}ntp.ntsc.ac.cn:123",
"{UDP}us.ntp.org.cn:123"
],
"denyLineTableQuery": true,
"denyLineTableBroadcast": true,
"congestionAlgorithm": "BBR",
"burstLimit": 1.5,
"delayUpperBound": 1.3,
"delayLowerBound": 1.3,
"nagleDelayTime": 1000000,
"linkNagleDelayTime": 0,
"linkConnectionsCount": 1,
"TUNName": "KLALB_SRv6",
"NetworkInterfaceExcepts": [],
"Type": "KLALBController"
},
{
"Listen": "0.0.0.0:4572",
"Bridge": {
"KLALB": "SocketBridge",
"RDP": "SocketBridge",
"HTTP": "SocketBridge",
"HTTPS": "SocketBridge",
"DEFAULT": "MinecraftSocketBridge23332"
},
"Connect": {
"KLALB": "127.0.0.1:4565",
"RDP": "127.0.0.1:3389",
"HTTP": "127.0.0.1:5212",
"HTTPS": "192.168.1.235:443",
"DEFAULT": "127.0.0.1:36555"
},
"Type": "SocketBridge"
},
{
"Listen": "{KLALB_Stream}[::0]:23332",
"Bridge": {
"DEFAULT": "MinecraftSocketBridge23332"
},
"Connect": {
"DEFAULT": "127.0.0.1:36555"
},
"Type": "SocketBridge"
},
{
"Listen": "{KLALB_Stream}[::0]:23333",
"Bridge": {
"DEFAULT": "SocketBridge"
},
"Connect": {
"DEFAULT": "127.0.0.1:5212"
},
"Type": "SocketBridge"
},
{
"Listen": "{KLALB_Stream}[::0]:25565",
"Bridge": {
"DEFAULT": "SocketBridge"
},
"Connect": {
"DEFAULT": "127.0.0.1:25566"
},
"Type": "SocketBridge"
},
{
"Listen": "0.0.0.0:25561",
"Bridge": {
"KLALB": "SocketBridge",
"DEFAULT": "MinecraftSocketBridge23330"
},
"Connect": {
"KLALB": "127.0.0.1:4565",
"DEFAULT": "127.0.0.1:25562"
},
"Type": "SocketBridge"
},
{
"Listen": "{KLALB_Stream}[::0]:23330",
"Bridge": {
"DEFAULT": "MinecraftSocketBridge23330"
},
"Connect": {
"DEFAULT": "127.0.0.1:25562"
},
"Type": "SocketBridge"
}
]
-3
View File
@@ -1,3 +0,0 @@
#Tue Jul 25 19:03:09 CST 2023
local=0.0.0.0\:35000
server=127.0.0.1\:4569
+79
View File
@@ -0,0 +1,79 @@
[
{"Type":"KLALBController" ,
"TCPListen" : "0.0.0.0:4565",
"UDPListen" : "{UDP}0.0.0.0:4572",
"VirtualSocketName" : "KLALB_Stream",
"LineTable":["43.248.189.107:65529",
"cn-bj-bgp-3.openfrp.top:65529",
"180.76.147.250:65529",
"cn-ah-dx-1.natfrp.cloud:65529",
"cn-nn-dx-1.natfrp.cloud:65529",
"cn-wh-dx-1.natfrp.cloud:65529",
"cn-zz-bgp-10.natfrp.cloud:23330",
"cn-zz-bgp-7.natfrp.cloud:33336",
"43.143.109.64:49965",
"frp.104300.xyz:49965",
"us.afrps.cn:49966",
"hk.afrps.cn:49966",
"la.afrps.cn:49966",
"frp.freefrp.net:49965",
"frp1.freefrp.net:49965",
"frp2.freefrp.net:49965",
"frp4.freefrp.net:49965",
"cn-he-plc-2.openfrp.top:4572",
"{UDP}cn-he-plc-2.openfrp.top:4572",
"frp-mom.top:22226",
"frp-man.top:36555",
"us-sjc-bgp-2.openfrp.top:36555",
"us-sjc-bgp-1.openfrp.top:36555",
"[240e:340:d856:b700:6d02:6a6a:f9fc:865b]:4572"]
},
{"Type":"SocketBridge" ,
"Listen" : "0.0.0.0:4572",
"Bridge":{
"KLALB" : "SocketBridge",
"RDP":"SocketBridge",
"HTTP":"SocketBridge",
"HTTPS":"SocketBridge",
"DEFAULT":"MinecraftSocketBridge23332"
} ,
"Connect" : {
"KLALB" : "127.0.0.1:4565",
"RDP":"127.0.0.1:3389",
"HTTP":"127.0.0.1:5212",
"HTTPS":"192.168.1.235:443",
"DEFAULT":"127.0.0.1:36555"
}
},
{"Type":"SocketBridge" ,
"Listen" : "{KLALB_Stream}[::0]:23332",
"Bridge":"MinecraftSocketBridge23332",
"Connect" : "127.0.0.1:36555"
},
{ "Type":"SocketBridge" ,
"Listen" : "{KLALB_Stream}[::0]:23333",
"Bridge":"SocketBridge",
"Connect" : "127.0.0.1:5212"
},
{"Type":"SocketBridge" ,
"Listen" : "0.0.0.0:25561",
"Bridge":{
"KLALB" : "SocketBridge",
"DEFAULT":"MinecraftSocketBridge23330"
} ,
"Connect" : {
"KLALB" : "127.0.0.1:4565",
"DEFAULT":"127.0.0.1:25562"
}
},
{"Type":"SocketBridge" ,
"Listen" : "{KLALB_Stream}[::0]:23330",
"Bridge":"MinecraftSocketBridge23330",
"Connect" : "127.0.0.1:25562"
}
]
-3
View File
@@ -1,3 +0,0 @@
virtualip=67c:72ce:765e:4db1:a02e:92fa:1959:29eb
bind=0.0.0.0:4569
local=127.0.0.1:36555
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
-2
View File
@@ -1,2 +0,0 @@
{UDP}192.168.1.233:4569
{UDP}192.168.0.233:4569

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

+107
View File
@@ -0,0 +1,107 @@
srv6acc=SRv6 network accelerator system
networkgraph=Network graph
language=Language
basicsettings=Basic settings
ipv6addr=IPv6 address
dnsserver=DNS server
asnumber=AS number
tcplistening=TCP listening
udplistening=UDP listening
openlinetable=Open line table
autoconnectlinetable=Auto connect line table
advancedsettings=Advanced settings
congresscontrolalgorithm=Congress control algorithm
savesettings=Save settings
locate=Locate
find=Find
home=Home
uploadspeed=Upload speed
downloadspeed=Download speed
uploadpps=Upload PPS
downloadpps=Download PPS
uploaddelay=Upload delay
downloaddelay=Download delay
copy=Copy
onlinedevices=Online devices
monitor=Monitor
showofflines=Show offline remotelines
lineaddressport=Line address:port
addline=Add line
reconnectall=Reconnect All
remotelines=Remote lines
settings=Settings
saveconfigsuccess=Save config success
warning=Warning
invaildipv6addr=IPv6 address:Invaild Input
invailddnsserver=DNS server:Invaild Input
invaildasnumber=AS number:Invaild Input
invaildtcplisten=TCP listen:Invaild Input
invaildudplisten=UDP listen:Invaild Input
invaildopenlinetable=Open line table:Invaild Input
invaildconnectlinetable=Connect line table:Invaild Input
invaildntpservertable=NTP server addresses:Invaild Input
unknown=Unknown
viewlinemonitor=View line monitor
copylineaddress=Copy line address
copyvirtualaddress=Copy virtual address
tryreconnect=Try reconnect
forcedisconnect=Force disconnect
removeline=Remove line
time=Time
speermonitor=Speed monitor
delaymonitor=Delay monitor
speed=Speed
delay=Delay
virtualnetsettings=Virtual network settings
tunnelnetsettings=Tunnel network settings
linksettings=Link settings
klalbperf=KLALB-perf Speedtest
speedtest=Network speed test
starttest=Start test
testreport=Test report
invaildinput=Invaild input
stoptest=Stop test
bandwidth=Bandwidth
nodeinf=Node information
selectinterface=Select network interface
add=Add
edit=Edit
remove=Remove
networkinterfaceexcept=Network interface except
cancel=Cancel
ok=Ok
currenttime=Current time
timesyncsettings=Time sync settings
ntpservers=NTP server addresses
nodeinfo=Node information
basicinfo=Basic info
overview=Overview
timerange=Time range
error=Error
securitysettings=Security settings
delayupperbound=Delay upper bound
delaylowerbound=Delay lower bound
denyaddrquery=Deny address query
denyaddrbroadcast=Deny address broadcast
random=Random
transmitnagledelaytime=Transmit nagle delay time
linknagledelaytime=Link nagle delay time
linkconnectionscount=Link connections count
tunname=Virtual network device name
dashboard=Dashboard
backplanedelay=Backplane delay
backplanepps=Backplane PPS
backplaneecnrate=Backplane ECN rate
backplanelossrate=Backplane Loss rate
uisettings=UI settings
nogui=No GUI mode
bufferusagemonitor=Buffer usage monitor
buffer=Buffer
usedbuffer=Used buffer
maxbuffer=Max buffer
queueused=Used queue
downloadbasedelay=Download Base
uploadbasedelay=Upload Base
burstlimit=Burst limit
performancesettings=Performance settings
performancestrategy=Performance strategy
+107
View File
@@ -0,0 +1,107 @@
srv6acc=SRv6 网络加速系统
networkgraph=网络拓扑图
language=语言
basicsettings=基本设置
ipv6addr=IPv6地址
dnsserver=DNS服务器
asnumber=AS号码
tcplistening=TCP监听端口
udplistening=UDP监听端口
openlinetable=开放线路列表
autoconnectlinetable=自动连接线路列表
advancedsettings=高级设置
congresscontrolalgorithm=拥塞控制算法
savesettings=保存设置
locate=定位
find=查找
home=本机
uploadspeed=上传速度
downloadspeed=下载速度
uploadpps=上传包转发率
downloadpps=下载包转发率
uploaddelay=上传延迟
downloaddelay=下载延迟
copy=复制
onlinedevices=在线设备
monitor=监视器
showofflines=显示离线远程链路
lineaddressport=链路地址:端口
addline=添加链路
reconnectall=全部重连
remotelines=远程链路
settings=设置
saveconfigsuccess=保存配置成功
warning=警告
invaildipv6addr=IPv6地址:非法输入
invailddnsserver=DNS服务器:非法输入
invaildasnumber=AS号码:非法输入
invaildtcplisten=TCP监听端口:非法输入
invaildudplisten=UDP监听端口:非法输入
invaildopenlinetable=开放线路列表:非法输入
invaildconnectlinetable=自动连接线路列表:非法输入
invaildntpservertable==NTP授时服务器地址:非法输入
unknown=未知
viewlinemonitor=打开链路监视器
copylineaddress=复制链路地址
copyvirtualaddress=复制虚拟地址
tryreconnect=立即尝试重连
forcedisconnect=强制断开连接
removeline=强制断开连接并移除
time=时间
speermonitor=速度监视器
delaymonitor=延迟监视器
speed=速度
delay=延迟
virtualnetsettings=虚拟网络设置
tunnelnetsettings=隧道网络设置
linksettings=链路设置
klalbperf=KLALB-perf网速测试
speedtest=网速测试
starttest=开始测试
testreport=测速报告
invaildinput=非法输入
stoptest=停止测试
bandwidth=带宽
nodeinf=节点信息
selectinterface=选择网卡
add=添加
edit=编辑
remove=移除
networkinterfaceexcept=网卡排除列表
cancel=取消
ok=确定
currenttime=当前时间
timesyncsettings=时钟同步设置
ntpservers=NTP授时服务器地址
nodeinfo=节点信息
basicinfo=基本信息
overview=概览
timerange=时间范围
error=错误
securitysettings=安全设置
delayupperbound=网络时延上限
delaylowerbound=网络时延下限
denyaddrquery=禁用IP地址查询
denyaddrbroadcast=禁用IP地址广播
random=随机
transmitnagledelaytime=传输粘包等待时间
linknagledelaytime=链路粘包等待时间
linkconnectionscount=链路连接数
tunname=虚拟网卡名称
dashboard=仪表盘
backplanedelay=背板处理延迟
backplanepps=背板包转发率
backplaneecnrate=背板ECN率
backplanelossrate=背板丢包率
uisettings=UI设置
nogui=无GUI模式
bufferusagemonitor=缓冲区监视器
buffer=缓冲区
usedbuffer=已用缓冲区
maxbuffer=最大缓冲区
queueused=已用队列
downloadbasedelay=下载延迟基线
uploadbasedelay=上传延迟基线
burstlimit=突发限制
performancesettings=性能设置
performancestrategy=性能策略
@@ -0,0 +1,75 @@
package org.kne.cloud.clock;
import java.util.concurrent.locks.ReentrantLock;
public class AdjustedNanoClock {
private ReentrantLock lock=new ReentrantLock();
public ReentrantLock getLock() {
return lock;
}
private volatile long delta=0;
private volatile long accuracy=Long.MAX_VALUE;
private boolean unsetted=true;
public long getCurrentTime() {
return System.nanoTime()+delta;
}
public AdjustedNanoClock(long delta) {
super();
this.delta = delta;
}
public AdjustedNanoClock() {
}
@Override
public String toString() {
return "AdjustedNanoClock [delta=" + delta + ", accuracy=" + accuracy + "]";
}
public long getDelta() {
return delta;
}
public void setDelta(long delta) {
this.delta = delta;
}
public void setCurrentTime(long curr) {
delta=curr-System.nanoTime();
}
public void setCurrentTime2(long curr) {
if(unsetted) {
unsetted=false;
delta=curr-System.nanoTime();
}else {
delta=(delta*9+ curr-System.nanoTime())/10;
}
}
public long getAccuracy() {
return accuracy;
}
public void calibrate(long delta,long taccurace) {
if(accuracy==Long.MAX_VALUE||taccurace<= accuracy) {
accuracy=taccurace;
unsetted=false;
this.delta=delta;
//System.out.println(delta+" "+currentTime+" "+taccurace);
}else {
accuracy=(accuracy*9999+taccurace)/10000;
}
}
public void calibrate2(long delta,long taccurace) {
if(accuracy==Long.MAX_VALUE||taccurace<= accuracy) {
accuracy=taccurace;
if(unsetted) {
unsetted=false;
this.delta=delta;
}else {
this.delta=(this.delta*9+delta)/10;
}
//System.out.println(delta+" "+currentTime+" "+taccurace);
}else {
accuracy=(accuracy*9999+taccurace)/10000;
}
}
}
@@ -0,0 +1,31 @@
package org.kne.cloud.clock;
public class ExponentialBackoffTimeClock {
private volatile long coolingTime=5000000000L;
{
resetCoolingTime();
}
public volatile long minCoolingTime=5000000000L,maxCoolingTime=300000000000L;
public ExponentialBackoffTimeClock(long minCoolingTime, long maxCoolingTime) {
super();
this.minCoolingTime = minCoolingTime;
this.maxCoolingTime = maxCoolingTime;
}
public ExponentialBackoffTimeClock() {
super();
}
public long getCoolingTime() {
return coolingTime;
}
public void incCoolingTime() {
coolingTime<<=1;
if(coolingTime>maxCoolingTime) {
coolingTime=maxCoolingTime;
}
}
public void resetCoolingTime() {
coolingTime=minCoolingTime;
}
}
@@ -0,0 +1,258 @@
package org.kne.cloud.clock;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.ReentrantLock;
import org.kne.math.Long128;
public class HighAccuracyClock {
private final long initialCPUNanoTime;
private final Long128 initialSystemNanoTime;
private volatile long baseCPUNanoTime;
private volatile Long128 baseSystemNanoTime;
private volatile long frequency=1000000000;//1000015000
private volatile long frequency2=frequency*0xffffffffL/1000000000L;
private ReentrantLock lock=new ReentrantLock();
private static final Long128 NANOS_PER_MILLIS = Long128.valueOf(TimeUnit.MILLISECONDS.toNanos(1));
private static final Long128 NANOS_PER_SECONDS = Long128.valueOf(TimeUnit.SECONDS.toNanos(1));
public static final HighAccuracyClock SYSTEM_CLOCK = new HighAccuracyClock();
public HighAccuracyClock() {
this.initialSystemNanoTime =Long128.valueOf( System.currentTimeMillis() ).multiply(NANOS_PER_MILLIS);
this.initialCPUNanoTime = System.nanoTime();
this.baseSystemNanoTime=initialSystemNanoTime;
this.baseCPUNanoTime=initialCPUNanoTime;
}
public long getFrequency() {
return frequency;
}
public void setFrequency(long frequency) {
lock.lock();
try {
long curr=System.nanoTime();
long nanoela=curr-baseCPUNanoTime;
baseCPUNanoTime=curr;
baseSystemNanoTime=baseSystemNanoTime.add( Long128.valueOf(nanoela).multiply(this.frequency).divide(NANOS_PER_SECONDS));
this.frequency = frequency;
this.frequency2=frequency*0xffffffffL/1000000000L;
}finally {
lock.unlock();
}
}
public void adjustFrequency(long fdelta) {
lock.lock();
try {
compact();
this.frequency = frequency+fdelta;
this.frequency2=frequency*0xffffffffL/1000000000L;
}finally {
lock.unlock();
}
}
private void compact() {
lock.lock();
try {
long curr=System.nanoTime();
long nanoela=curr-baseCPUNanoTime;
baseCPUNanoTime=curr;
baseSystemNanoTime=baseSystemNanoTime.add(Long128.valueOf(nanoela).multiply(this.frequency).divide(NANOS_PER_SECONDS));
}finally {
lock.unlock();
}
}
/**
* 获取从1970-01-01开始的当前时间(纳秒精度)
*/
public Long128 getCurrentTimeNanos() {
Long128 mul=Long128.valueOf(System.nanoTime()-baseCPUNanoTime).multiply(frequency2);
return mul.shiftRight(32).add(baseSystemNanoTime);
}
/**
* 获取从1970-01-01开始的当前时间(毫秒精度)
*/
public long getCurrentTimeMillis() {
return getCurrentTimeNanos().divide(NANOS_PER_MILLIS).longValue();
}
/**
* 获取 NTPv4 128 位时间戳
*/
public Long128 getCurrentTimeNTP128() {
return NTPTimestamps.nanosToNtp128BitTimestamp(getCurrentTimeNanos());
}
/**
* 获取 NTPv4 64 位时间戳
*/
public Long128 getCurrentTimeNTP64() {
return NTPTimestamps.ntp128To64(getCurrentTimeNTP128());
}
/**
* 获取时钟创建以来经过的时间(纳秒)
*/
public long getElapsedNanos() {
return System.nanoTime() - initialCPUNanoTime;
}
// ================== 修复的时间同步方法 ==================
/**
* 强制同步到指定时间(正确版本)
* @param targetNanos 目标时间(从1970年开始的纳秒数)
*/
public void syncToTime(Long128 targetNanos) {
lock.lock();
try {
baseCPUNanoTime= System.nanoTime();
baseSystemNanoTime=targetNanos;
}finally {
lock.unlock();
}
}
/**
* 基于参考时钟进行同步(更安全的方法)
* @param referenceClock 参考时钟
*/
public void syncToClock(HighAccuracyClock referenceClock) {
syncToClock(referenceClock,BigInteger.ZERO);
}
/**
* 基于参考时钟进行同步(更安全的方法)
* @param referenceClock 参考时钟
* @param delta 网络延迟(纳秒),可选
*/
public void syncToClock(HighAccuracyClock referenceClock, BigInteger delta) {
if (delta == null) {
delta = BigInteger.ZERO;
}
lock.lock();
try {
baseCPUNanoTime=System.nanoTime();
baseSystemNanoTime=referenceClock.getCurrentTimeNanos();
}finally {
lock.unlock();
}
}
/**
* 基于NTP时间戳同步
* @param ntp128Timestamp NTP 128位时间戳
*/
public void syncToNTPTime(Long128 ntp128Timestamp) {
Long128 targetNanos = NTPTimestamps.ntp128BitToNanosTimestamp(ntp128Timestamp);
syncToTime(targetNanos);
}
/**
* 调整时钟(用于时间同步)
* @param delta 要调整的纳秒数(正数调快,负数调慢)
*/
public void adjustClock(Long128 delta) {
lock.lock();
try {
baseSystemNanoTime = baseSystemNanoTime.add(delta);
}finally {
lock.unlock();
}
}
/**
* 调整时钟(用于时间同步)
* @param delta 要调整的纳秒数(正数调快,负数调慢)
*/
public void adjustClock(Long128 delta, double adjPercent) {
BigInteger adjustment=new BigDecimal(delta.toBigInteger()).multiply(BigDecimal.valueOf( adjPercent)).toBigInteger();
lock.lock();
try {
baseSystemNanoTime = baseSystemNanoTime.add(Long128 .valueOf(adjustment));
}finally {
lock.unlock();
}
}
/**
* 获取时钟偏差(当前时间与真实时间的差异)
*/
public Long128 getClockError(Long128 referenceTime) {
return getCurrentTimeNanos().subtract(referenceTime);
}
/**
* 检查时钟是否同步(误差在允许范围内)
*/
public boolean isSynchronized(Long128 referenceTime, Long128 tolerance) {
Long128 error = getClockError(referenceTime).abs();
return error.compareTo(tolerance) <= 0;
}
// ================== toString 方法 ==================
/**
* 转换为详细格式的字符串(包含纳秒)
*/
public String toString() {
Long128 nanos = getCurrentTimeNanos();
return NTPTimestamps.nanosSince1970ToString(nanos);
}
public String toString2() {
Long128 nanos = getCurrentTimeNanos();
return NTPTimestamps.nanosSince1970ToString2(nanos);
}
public long getInitialCPUNanoTime() {
return initialCPUNanoTime;
}
public Long128 getInitialSystemNanoTime() {
return initialSystemNanoTime;
}
public static void main(String[] args) throws InterruptedException {
HighAccuracyClock hac=new HighAccuracyClock();
while(true) {
System.out.println(hac.getCurrentTimeNanos());
Thread.sleep(1000);
}
}
}
+259
View File
@@ -0,0 +1,259 @@
package org.kne.cloud.clock;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import org.kne.math.Long128;
public class NTPTimestamps {
// 常量定义
public static final Long128 NANOS_PER_SECOND = Long128.valueOf(1_000_000_000L);
public static final Long128 NANOS_PER_MILLIS = Long128.valueOf(1_000_000L);
// NTP 纪元 (1900) 和 Unix 纪元 (1970) 之间的纳秒差
public static final Long128 NTP_EPOCH_OFFSET_NS = Long128.valueOf(2208988800L)
.multiply(NANOS_PER_SECOND);
// 2^64 值,用于单位转换
public static final Long128 TWO_POW_64 = Long128.ONE.shiftLeft(64);
// 2^32 值,用于 64 位时间戳处理
public static final Long128 TWO_POW_32 = Long128.ONE.shiftLeft(32);
// 掩码常量
public static final Long128 MASK_32_BIT = new Long128(0xFFFFFFFF);
public static final Long128 MASK_64_BIT = new Long128(0xFFFFFFFFFFFFFFFFL);
// ================== 核心转换方法 ==================
// 2^32 秒,约 136.192 年,一个 NTP 纪元的长度
public static final Long128 SECONDS_PER_ERA = Long128.valueOf(0x100000000L);
private static final Long128 TWO_POW_N64_PER_NANOS = Long128.valueOf("1208925819614629");
public static Long128 inferNtp64To128(long remote64Bit,Long128 local128Bit ) {
return inferNtp64To128(toUnsignedLong128(remote64Bit),local128Bit);
}
/**
* 根据本地 128 位时间戳和网络 64 位时间戳,推断并补全纪元信息
*
* @param remote64Bit 从网络接收的 64 位 NTP 时间戳
* @param local128Bit 本地已知的 128 位 NTP 时间戳
* @return 推断出的完整 128 位 NTP 时间戳
*/
public static Long128 inferNtp64To128(Long128 remote64Bit,Long128 local128Bit ) {
// 1. 从本地 128 位时间戳中提取纪元号和 64 位时间戳部分
Long128 localEra = NTPTimestamps.getEraNumber(local128Bit);
Long128 local64Bit = NTPTimestamps.getNtp64Timestamp(local128Bit);
// 3. 计算本地和远程 64 位时间戳的差异
Long128 difference = remote64Bit.subtract(local64Bit);
// 4. 判断纪元关系并推断远程时间戳的纪元
Long128 remoteEra;
// 如果差异很大(超过半个纪元),可能需要调整纪元
Long128 halfEra = Long128.valueOf(Long.MAX_VALUE);
if (difference.compareTo(halfEra) > 0) {
// 远程时间戳比本地小很多,可能属于上一个纪元
remoteEra = localEra.subtract(Long128.ONE);
} else if (difference.compareTo(halfEra.negate()) < 0) {
// 远程时间戳比本地大很多,可能属于下一个纪元
remoteEra = localEra.add(Long128.ONE);
} else {
// 差异不大,属于同一个纪元
remoteEra = localEra;
}
// 5. 组合纪元号和 64 位时间戳,得到完整的 128 位时间戳
return NTPTimestamps.ntp64To128(remote64Bit, remoteEra);
}
/**
* 将从1970年开始的纳秒数转换为 NTPv4 128 位时间戳
* 128位时间戳表示从1900年1月1日起经过的 2⁻⁶⁴ 秒的数量
*/
public static Long128 nanosToNtp128BitTimestamp(Long128 nanosSince1970) {
// 1. 计算从 1900 年开始的总纳秒数
Long128 totalNanosFrom1900 = nanosSince1970.add(NTP_EPOCH_OFFSET_NS);
// 2. 将纳秒转换为 2⁻⁶⁴ 秒单位
// return totalNanosFrom1900.multiply(TWO_POW_64).divide(NANOS_PER_SECOND);
return totalNanosFrom1900.multiply(TWO_POW_N64_PER_NANOS).shiftRight(16);
}
/**
* 从 NTPv4 128 位时间戳转换回从1970年开始的纳秒数
*/
public static Long128 ntp128BitToNanosTimestamp(Long128 ntp128Timestamp) {
// 1. 将 2⁻⁶⁴ 秒单位转换回纳秒
Long128 totalNanosFrom1900 = ntp128Timestamp.multiply(NANOS_PER_SECOND).divide(TWO_POW_64);
// 2. 计算从 1970 年开始的总纳秒数
return totalNanosFrom1900.subtract(NTP_EPOCH_OFFSET_NS);
}
public static Long128 nanosToNtp128BitTimeInterval(Long128 nanos) {
// 2. 将纳秒转换为 2⁻⁶⁴ 秒单位
return nanos.multiply(TWO_POW_64).divide(NANOS_PER_SECOND);
}
public static Long128 ntp128BitToNanosInterval(Long128 ntp128Timestamp) {
// 1. 将 2⁻⁶⁴ 秒单位转换回纳秒
Long128 totalNanosFrom1900 = ntp128Timestamp.multiply(NANOS_PER_SECOND).divide(TWO_POW_64);
return totalNanosFrom1900;
}
// ================== 128位 ↔ 64位 转换 ==================
/**
* 将 NTP 128 位时间戳转换为 NTP 64 位时间戳
* 64位时间戳就是128位时间戳的中间64位
*/
public static Long128 ntp128To64(Long128 ntp128Timestamp) {
return ntp128Timestamp.shiftRight(32).and(MASK_64_BIT);
}
/**
* 将 NTP 64 位时间戳转换为 NTP 128 位时间戳
* 64位时间戳放在128位时间戳的中间64位,高32位Era和低32位分数为0
*/
public static Long128 ntp64To128(Long128 ntp64Timestamp) {
return ntp64Timestamp.and(MASK_64_BIT).shiftLeft(32);
}
/**
* 将 NTP 64 位时间戳转换为 NTP 128 位时间戳(指定Era Number
*/
public static Long128 ntp64To128(Long128 ntp64Timestamp, Long128 eraNumber) {
return eraNumber.and(MASK_32_BIT).shiftLeft(96)
.or(ntp64Timestamp.and(MASK_64_BIT).shiftLeft(32));
}
/**
* 从 NTP 128 位时间戳中提取 Era Number(高32位)
*/
public static Long128 getEraNumber(Long128 ntp128Timestamp) {
return ntp128Timestamp.shiftRight(96).and(MASK_32_BIT);
}
/**
* 从 NTP 128 位时间戳中提取 64 位时间戳(中间64位)
*/
public static Long128 getNtp64Timestamp(Long128 ntp128Timestamp) {
return ntp128Timestamp.shiftRight(32).and(MASK_64_BIT);
}
/**
* 从 NTP 128 位时间戳中提取分数部分(低32位)
*/
public static Long128 getFraction(Long128 ntp128Timestamp) {
return ntp128Timestamp.and(MASK_32_BIT);
}
// ================== 工具方法 ==================
/**
* 从毫秒和纳秒偏移构造 Long128 纳秒
*/
public static Long128 toNanosSince1970(long unixTimeMillis, long nanosOffset) {
return Long128.valueOf(unixTimeMillis)
.multiply( NANOS_PER_MILLIS)
.add(Long128.valueOf(nanosOffset));
}
/**
* 从 Long128 纳秒提取毫秒和纳秒偏移
*/
public static long[] toMillisAndNanos(Long128 nanosSince1970) {
Long128[] millisAndNanos = nanosSince1970.divideAndRemainder( NANOS_PER_MILLIS);
return new long[]{millisAndNanos[0].longValue(), millisAndNanos[1].longValue()};
}
/**
* 计算两个 128 位时间戳之间的时间差(纳秒)
*/
public static Long128 calculateTimeDifference(Long128 timestamp1, Long128 timestamp2) {
Long128 diff = timestamp2.subtract(timestamp1);
return diff.multiply(NANOS_PER_SECOND).divide(TWO_POW_64);
}
/**
* 将 64 位 NTP 时间戳分解为秒数和分数
*/
public static Long128[] parseNtp64Timestamp(Long128 ntp64Timestamp) {
Long128 seconds = ntp64Timestamp.shiftRight(32).and(MASK_32_BIT);
Long128 fraction = ntp64Timestamp.and(MASK_32_BIT);
return new Long128[]{seconds, fraction};
}
/**
* 从秒数和分数构建 64 位 NTP 时间戳
*/
public static Long128 buildNtp64Timestamp(Long128 seconds, Long128 fraction) {
return seconds.and(MASK_32_BIT).shiftLeft(32).or(fraction.and(MASK_32_BIT));
}
// 日期时间格式化器
private static final DateTimeFormatter DEFAULT_FORMATTER =
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
private static final DateTimeFormatter DETAILED_FORMATTER =
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.n");
public static String nanosSince1970ToString(Long128 nanos) {
Long128 millis = nanos.divide(Long128.valueOf(1_000_000));
Long128 nanosPart = nanos.mod(Long128.valueOf(1_000_000));
Instant instant = Instant.ofEpochMilli(millis.longValue());
LocalDateTime dateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
return String.format("%s.%06d",
DEFAULT_FORMATTER.format(dateTime),
nanosPart.longValue());
}
public static String nanosSince1970ToString2(Long128 nanos) {
Long128 millis = nanos.divide(Long128.valueOf(1_000_000));
Instant instant = Instant.ofEpochMilli(millis.longValue());
LocalDateTime dateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
return DEFAULT_FORMATTER.format(dateTime);
}
/**
* 将 128 位时间戳转换为可读字符串
*/
public static String ntp128ToString(Long128 ntp128Timestamp) {
Long128 nanosSince1970 = ntp128BitToNanosTimestamp(ntp128Timestamp);
return nanosSince1970ToString(nanosSince1970);
}
/**
* 将 64 位时间戳转换为可读字符串
*/
public static String ntp64ToString(Long128 ntp64Timestamp) {
Long128 nanosSince1970 = ntp128BitToNanosTimestamp(ntp64To128( ntp64Timestamp));
return nanosSince1970ToString(nanosSince1970);
}
public static Long128 toUnsignedLong128(long unsignedLong) {
if (unsignedLong >= 0) {
return Long128.valueOf(unsignedLong);
} else {
// 对于负数,通过添加 2^64 来转换为无符号表示
return Long128.valueOf(unsignedLong & 0x7FFFFFFFFFFFFFFFL)
.setBit(63);
}
}
}
@@ -0,0 +1,16 @@
package org.kne.cloud.clock;
public class ReliabilityBackoffTimeClock {
public volatile long maxCoolingTime=300000000000L;
public ReliabilityBackoffTimeClock(long maxCoolingTime) {
super();
this.maxCoolingTime = maxCoolingTime;
}
public ReliabilityBackoffTimeClock() {
super();
}
public long getCoolingTime(double reliability) {
return (long) ((1.0-reliability)*maxCoolingTime);
}
}
@@ -0,0 +1,19 @@
package org.kne.cloud.clock;
public class WatchDogTimer {
private volatile long feedtime=System.nanoTime();
private long timeout;
public WatchDogTimer(long timeout) {
super();
this.timeout = timeout;
}
public void feed() {
feedtime=System.nanoTime();
}
public boolean isBarking() {
return(System.nanoTime()-feedtime)>timeout;
}
}
@@ -0,0 +1,41 @@
package org.kne.cloud.klalb.uitool;
import java.awt.Color;
import java.awt.Font;
import java.awt.font.TextAttribute;
import java.util.Collections;
import java.util.Map;
import javax.swing.JButton;
import javax.swing.JTextField;
import java.awt.BorderLayout;
import javax.swing.SwingConstants;
import org.kne.cloud.network.klalb.ui.UIEnv;
public class ButtonSettingItem extends SettingItem {
protected JButton button;
public JButton getButton() {
return button;
}
public ButtonSettingItem(String text,int w,int h) {
this(text,UIEnv.getFont().deriveFont((float) 15.0),w,h);
}
/**
* @wbp.parser.constructor
*/
public ButtonSettingItem(String text, Font deriveFont,int w,int h) {
super(text,deriveFont,w,h);
button = new JButton(UIEnv.getRsb().getString("clicktoopen")+">>");
button.setHorizontalAlignment(SwingConstants.RIGHT);
button.setFont(button.getFont().deriveFont(Map.of(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON)));
getPanel().add(button, BorderLayout.EAST);
button.setBorder(null);
button.setOpaque(false);
button.setBackground(new Color(0,0,0,0));
label.setForeground(Color.GRAY);
}
}
@@ -0,0 +1,37 @@
package org.kne.cloud.klalb.uitool;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.SwingConstants;
import org.kne.cloud.klalb.uitool.SettingItem;
import org.kne.cloud.network.klalb.ui.UIEnv;
public class CheckBoxSettingItem extends SettingItem {
protected JCheckBox button;
public JCheckBox getCheckBox() {
return button;
}
public CheckBoxSettingItem(String text,int w,int h) {
this(text,UIEnv.getFont().deriveFont((float) 15.0),w,h);
}
/**
* @wbp.parser.constructor
*/
public CheckBoxSettingItem(String text, Font deriveFont,int w,int h) {
super(text,deriveFont,w,h);
button = new JCheckBox();
button.setHorizontalAlignment(SwingConstants.RIGHT);
getPanel().add(button, BorderLayout.CENTER);
button.setBorder(null);
button.setOpaque(false);
button.setBackground(new Color(0,0,0,0));
label.setForeground(Color.GRAY);
}
}
@@ -0,0 +1,33 @@
package org.kne.cloud.klalb.uitool;
import java.awt.Color;
import java.awt.Font;
import javax.swing.JTextField;
import java.awt.BorderLayout;
import javax.swing.SwingConstants;
import org.kne.cloud.network.klalb.ui.UIEnv;
import javax.swing.JComboBox;
public class ComboSettingItem extends SettingItem {
private JComboBox comboBox;
public JComboBox getComboBox() {
return comboBox;
}
public ComboSettingItem(String text,int w,int h) {
this(text,UIEnv.getFont().deriveFont((float) 15.0),w, h);
}
/**
* @wbp.parser.constructor
*/
public ComboSettingItem(String text, Font deriveFont,int w,int h) {
super(text,deriveFont,w,h);
label.setForeground(Color.GRAY);
comboBox = new JComboBox();
comboBox.setOpaque(false);
getPanel().add(comboBox, BorderLayout.CENTER);
}
}
@@ -0,0 +1,86 @@
package org.kne.cloud.klalb.uitool;
import javax.swing.JDialog;
import javax.swing.JFrame;
import java.awt.Dimension;
import java.awt.TextArea;
import java.awt.BorderLayout;
import java.awt.Panel;
import java.awt.Window;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingConstants;
import org.kne.cloud.network.klalb.ui.UIEnv;
import javax.swing.ImageIcon;
import java.awt.Label;
import java.awt.Color;
import java.awt.Font;
import java.awt.TextField;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Random;
public class CrashReport extends JDialog{
private JLabel name;
private TextField type;
private JTextArea stack;
public CrashReport(Window parent ,boolean modal) {
super(parent);
setModal(modal);
setTitle("错误");
setIconImage(UIEnv.getIcon());
setSize(500, 400);
setLocationRelativeTo(null);
stack = new JTextArea();
stack.setEditable(false);
getContentPane().add(new JScrollPane(stack), BorderLayout.CENTER);
Panel panel = new Panel();
panel.setPreferredSize(new Dimension(500, 100));
getContentPane().add(panel, BorderLayout.NORTH);
panel.setLayout(null);
JLabel lblNewLabel = new JLabel("");
lblNewLabel.setIcon(new ImageIcon(CrashReport.class.getResource("/assets/error.jpg")));
lblNewLabel.setHorizontalAlignment(SwingConstants.CENTER);
lblNewLabel.setBounds(10, 10, 80, 80);
panel.add(lblNewLabel);
name = new JLabel("");
name.setFont(new Font("宋体", Font.PLAIN, 30));
name.setForeground(Color.RED);
name.setBounds(96, 10, 378, 33);
panel.add(name);
type = new TextField();
type.setEditable(false);
type.setBounds(96, 67, 378, 23);
panel.add(type);
fny = new JLabel("...?");
fny.setFont(new Font("MS Song", Font.PLAIN, 10));
getContentPane().add(fny, BorderLayout.SOUTH);
}
String []s=new String[]{"鎴戜滑鍥㈤槦鍙湁涓涓▼搴忓憳",
"鎯虫洿鏂帮紝娌¢棬",
"鎴戜滑鐨勬湇鍔″櫒鐪熺殑鏄笓涓氣滃埌瀹垛濅簡",
"杩炴帴宸蹭涪澶憋細涓嶅幓鍋氬惎鍔ㄥ櫒灏卞幓濂宠锛屼笉鍘诲コ瑁呭氨鍘诲仛鍚姩鍣",
"鍦熻眴鏈嶅姟鍣ㄥ張鍙戣娊浜"
};
private JLabel fny;
public void report(Throwable e,String t){
e.printStackTrace();
name.setText(t);
type.setText(e.getClass().getName());
StringWriter sw=new StringWriter();
PrintWriter pw=new PrintWriter(sw);
e.printStackTrace(pw);
pw.close();
stack.setText(sw.toString());fny.setText(s[new Random().nextInt(s.length)]);
setVisible(true);
}
}
@@ -23,7 +23,7 @@
* *
*/ */
package org.knemcl.uitool; package org.kne.cloud.klalb.uitool;
import javax.swing.*; import javax.swing.*;
import javax.swing.plaf.*; import javax.swing.plaf.*;
@@ -0,0 +1,159 @@
package org.kne.cloud.klalb.uitool;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.NetworkInterface;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Supplier;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ListModel;
import java.awt.BorderLayout;
import javax.swing.SwingConstants;
import org.kne.cloud.network.klalb.ui.UIEnv;
import java.awt.FlowLayout;
public abstract class ListSettingItem<T> extends SettingItem {
/**
*
*/
private static final long serialVersionUID = 1L;
protected JList<T> list;
private Consumer<T> storeRecall;
public JList<T> getList() {
return list;
}
public ListSettingItem(String text,int w,int h,XDefaultListModel<T>lm) {
this(text,UIEnv.getFont().deriveFont((float) 15.0),w,h,lm);
}
/**
* @wbp.parser.constructor
*/
public ListSettingItem(String text, Font deriveFont,int w,int h,XDefaultListModel<T> lm) {
super(text,deriveFont,w,h);
list = new JList<T>(lm);
JScrollPane js=new JScrollPane(list);
js.getViewport().setOpaque(false);
js.setOpaque(false);
js.setBackground(new Color(0,0,0,0));
getPanel().add(js, BorderLayout.CENTER);
list.setBorder(null);
list.setOpaque(false);
list.setBackground(new Color(0,0,0,0));
label.setForeground(Color.GRAY);
Dimension dss=new Dimension(25,25);
JButton jbt3x=new JButton();
jbt3x.setToolTipText(UIEnv.getRsb().getString("add"));
try {
jbt3x.setIcon(new ImageIcon(ImageIO .read(ListSettingItem.class.getResourceAsStream("/assets/add.png")).getScaledInstance(dss.width-2, dss.height-2, Image.SCALE_SMOOTH)));
} catch (IOException e) {
e.printStackTrace();
}catch (IllegalArgumentException e) {
e.printStackTrace();
}
jbt3x.setSize(dss);
jbt3x.setPreferredSize(dss);
jbt3x.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
List<T> x=createEmpty();
if(x!=null&&!x.isEmpty())
runEdit(x.get(0));
}
});
JButton jbedit=new JButton();
jbedit.setToolTipText(UIEnv.getRsb().getString("edit"));
try {
jbedit.setIcon(new ImageIcon(ImageIO .read(ListSettingItem.class.getResourceAsStream("/assets/edit-fill.png")).getScaledInstance(dss.width-2, dss.height-2, Image.SCALE_SMOOTH)));
} catch (IOException e) {
e.printStackTrace();
}catch (IllegalArgumentException e) {
e.printStackTrace();
}
jbedit.setSize(dss);
jbedit.setPreferredSize(dss);
jbedit.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
T val=list.getSelectedValue();
if(val!=null)
runEdit(val);
}
});
JButton jbt4x=new JButton();
jbt4x.setToolTipText(UIEnv.getRsb().getString("remove"));
try {
jbt4x.setIcon(new ImageIcon(ImageIO .read(ListSettingItem.class.getResourceAsStream("/assets/delete-bin-fill.png")).getScaledInstance(dss.width-2, dss.height-2, Image.SCALE_SMOOTH)));
} catch (IOException e) {
e.printStackTrace();
}catch (IllegalArgumentException e) {
e.printStackTrace();
}
jbt4x.setSize(dss);
jbt4x.setPreferredSize(dss);
jbt4x.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int v=list.getSelectedIndex();
if(v>=0) {
lm.remove(v);
if(storeRecall!=null)
storeRecall.accept(list.getSelectedValue());
}
}
});
JPanel jp=new JPanel();
jp.setPreferredSize(new Dimension(30, h));
FlowLayout flowLayout = (FlowLayout) jp.getLayout();
flowLayout.setAlignment(FlowLayout.TRAILING);
jp.setOpaque(false);
getPanel().add(jp,BorderLayout.EAST);
jp.add(jbt3x);
jp.add(jbedit);
jp.add(jbt4x);
}
abstract protected void runEdit(T val) ;
abstract protected List<T> createEmpty() ;
public void doAdd(T v) {
boolean b=true;
for (int i = 0; i < list.getModel().getSize(); i++) {
if(list.getModel().getElementAt(i)==v) {
b=false;
break;
}
}
if(b)
((XDefaultListModel<T>) list.getModel()).addElement(v);
repaint();
if(storeRecall!=null)
storeRecall.accept(list.getSelectedValue());
}
public Consumer<T> getStoreRecall() {
return storeRecall;
}
public void setStoreRecall(Consumer<T> storeRecall) {
this.storeRecall = storeRecall;
}
}
@@ -0,0 +1,134 @@
package org.kne.cloud.klalb.uitool;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.util.function.Consumer;
import java.util.function.Supplier;
import javax.swing.*;
import org.kne.cloud.network.klalb.ui.UIEnv;
public class PathInput extends JDialog {
private JTextField textField;
private boolean checkfile=true;
private boolean isdir=false;
protected JFileChooser jfc;
private Consumer<File> al;
public Consumer<File> getAl() {
return al;
}
public void setAl(Consumer<File> al) {
this.al = al;
}
public PathInput(Window d){
super(d);
setResizable(false);
setModal(true);
setSize(500, 110);
setLocationRelativeTo(d);
setIconImage(UIEnv.getIcon());
textField = new JTextField();
textField.setPreferredSize(new Dimension(400,80));
textField.setFont(new Font("微软雅黑", Font.PLAIN, 12));
getContentPane().add(textField, BorderLayout.CENTER);
textField.setColumns(10);
JPanel panel = new JPanel();
getContentPane().add(panel, BorderLayout.SOUTH);
JButton btnok = new JButton(UIEnv.getRsb().getString("ok"));
UIEnv.defbut(btnok);
panel.add(btnok);
btnok.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
File x=new File(textField.getText());
if(!checkfile){
if(isdir){
x.mkdirs();
}else{
try {
x.createNewFile();
} catch (IOException e1) {
e1.printStackTrace();
}
}
al.accept(x);
setVisible(false);
return;
}
if(x.exists()){
al.accept(x);
setVisible(false);
}else{
JOptionPane.showMessageDialog(PathInput.this, UIEnv.getRsb().getString("filenotexist"), UIEnv.getRsb().getString("error"), JOptionPane.ERROR_MESSAGE);
}
}
});
JButton btnNewButton_1 = new JButton(UIEnv.getRsb().getString("browse"));
UIEnv.defbut(btnNewButton_1);
panel.add(btnNewButton_1);
btnNewButton_1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if(jfc.showOpenDialog(PathInput.this)==jfc.APPROVE_OPTION){
textField.setText(jfc.getSelectedFile().toString());
}
/*File f=choose.get();
if(f!=null){
textField.setText(f.toString());
}*/
}
});
JButton button = new JButton(UIEnv.getRsb().getString("cancel"));
UIEnv.defbut(button);
panel.add(button);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setVisible(false);
}
});
jfc=new JFileChooser();
jfc.setMultiSelectionEnabled(false);
}
public JTextField getTextField() {
return textField;
}
public JFileChooser getJfc() {
return jfc;
}
public boolean isCheckfile() {
return checkfile;
}
public void setCheckfile(boolean checkfile) {
this.checkfile = checkfile;
}
public boolean isIsdir() {
return isdir;
}
public void setIsdir(boolean isdir) {
this.isdir = isdir;
if(isdir) {
jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
}else {
jfc.setFileSelectionMode(JFileChooser.FILES_ONLY);
}
}
}
@@ -0,0 +1,38 @@
package org.kne.cloud.klalb.uitool;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JRadioButton;
import javax.swing.SwingConstants;
import org.kne.cloud.klalb.uitool.SettingItem;
import org.kne.cloud.network.klalb.ui.UIEnv;
public class RadioButtonSettingItem extends SettingItem {
protected JRadioButton button;
public JRadioButton getRadioButton() {
return button;
}
public RadioButtonSettingItem(String text,int w,int h) {
this(text,UIEnv.getFont().deriveFont((float) 15.0),w,h);
}
/**
* @wbp.parser.constructor
*/
public RadioButtonSettingItem(String text, Font deriveFont,int w,int h) {
super(text,deriveFont,w,h);
button = new JRadioButton();
button.setHorizontalAlignment(SwingConstants.RIGHT);
getPanel().add(button, BorderLayout.CENTER);
button.setBorder(null);
button.setOpaque(false);
button.setBackground(new Color(0,0,0,0));
label.setForeground(Color.GRAY);
}
}
@@ -0,0 +1,52 @@
package org.kne.cloud.klalb.uitool;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.border.LineBorder;
import org.kne.cloud.network.klalb.ui.UIEnv;
import javax.swing.SwingConstants;
import javax.swing.SpringLayout;
public class SettingItem extends JPanel {
protected JLabel label;
private JPanel sub;
public JLabel getLabel() {
return label;
}
public SettingItem(String text,int w,int h){
this(text,UIEnv.getFont().deriveFont(15.0f),w,h);
}
public JPanel getPanel(){
return sub;
}
/**
* @wbp.parser.constructor
*/
public SettingItem(String text,Font f,int w,int h){
setSize(w, h);
setPreferredSize(new Dimension(w, h));
setBackground(UIEnv.getHalfTransparentDefaultColor());
SpringLayout springLayout = new SpringLayout();
setLayout(springLayout);
//setOpaque(false);
sub = new JPanel();
springLayout.putConstraint(SpringLayout.NORTH, sub, 0, SpringLayout.NORTH, this);
springLayout.putConstraint(SpringLayout.WEST, sub, 20, SpringLayout.WEST, this);
springLayout.putConstraint(SpringLayout.SOUTH, sub, 0, SpringLayout.SOUTH, this);
springLayout.putConstraint(SpringLayout.EAST, sub, -20, SpringLayout.EAST, this);
sub.setOpaque(false);
add(sub);
sub.setLayout(new BorderLayout(5, 0));
label = new JLabel(text);
label.setFont(f);
sub.add(label, BorderLayout.WEST);
}
}
@@ -0,0 +1,51 @@
package org.kne.cloud.klalb.uitool;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.font.TextAttribute;
import java.util.Map;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JSlider;
import javax.swing.JTextField;
import java.awt.BorderLayout;
import javax.swing.SwingConstants;
import org.kne.cloud.network.klalb.ui.UIEnv;
public class SliderSettingItem extends SettingItem {
protected JSlider slider;
protected JLabel labelx;
public JLabel getLabelx() {
return labelx;
}
public JSlider getSlider() {
return slider;
}
public SliderSettingItem(String text,int w,int h) {
this(text,UIEnv.getFont().deriveFont((float) 15.0),w,h);
}
/**
* @wbp.parser.constructor
*/
public SliderSettingItem(String text, Font deriveFont,int w,int h) {
super(text,deriveFont,w,h);
BorderLayout borderLayout = (BorderLayout) getPanel().getLayout();
slider = new JSlider();
getPanel().add(slider, BorderLayout.CENTER);
slider.setBorder(null);
slider.setOpaque(false);
slider.setBackground(new Color(0,0,0,0));
label.setForeground(Color.GRAY);
labelx = new JLabel();
getPanel().add(labelx, BorderLayout.EAST);
labelx.setFont(labelx.getFont());
labelx.setBorder(null);
labelx.setOpaque(false);
labelx.setBackground(new Color(0,0,0,0));
labelx.setPreferredSize(new Dimension(40, h));
}
}
@@ -0,0 +1,41 @@
package org.kne.cloud.klalb.uitool;
import java.awt.Color;
import java.awt.Font;
import javax.swing.JButton;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import java.awt.BorderLayout;
import javax.swing.SwingConstants;
import org.kne.cloud.network.klalb.ui.UIEnv;
public class TextAreaSettingItem extends SettingItem {
protected JTextArea textarea;
public JTextArea getTextArea() {
return textarea;
}
public TextAreaSettingItem(String text,int w,int h) {
this(text,UIEnv.getFont().deriveFont((float) 15.0),w,h);
}
/**
* @wbp.parser.constructor
*/
public TextAreaSettingItem(String text, Font deriveFont,int w,int h) {
super(text,deriveFont,w,h);
textarea = new JTextArea();
JScrollPane sp=new JScrollPane(textarea);
sp.getViewport().setOpaque(false);
sp.setOpaque(false);
sp.setBackground(new Color(0,0,0,0));
getPanel().add(sp, BorderLayout.CENTER);
textarea.setBorder(null);
textarea.setOpaque(false);
textarea.setBackground(new Color(0,0,0,0));
//textarea.setBackground(UIEnv.getDefaultcolor());
label.setForeground(Color.GRAY);
}
}
@@ -0,0 +1,49 @@
package org.kne.cloud.klalb.uitool;
import java.awt.Color;
import java.awt.Font;
import java.awt.font.TextAttribute;
import java.util.Map;
import javax.swing.JButton;
import javax.swing.JTextField;
import java.awt.BorderLayout;
import javax.swing.SwingConstants;
import org.kne.cloud.network.klalb.ui.UIEnv;
public class TextButtonSettingItem extends SettingItem {
protected JTextField textField;
protected JButton button;
public JButton getButton() {
return button;
}
public JTextField getTextField() {
return textField;
}
public TextButtonSettingItem(String text,int w,int h) {
this(text,UIEnv.getFont().deriveFont((float) 15.0),w,h);
}
/**
* @wbp.parser.constructor
*/
public TextButtonSettingItem(String text, Font deriveFont,int w,int h) {
super(text,deriveFont,w,h);
BorderLayout borderLayout = (BorderLayout) getPanel().getLayout();
textField = new JTextField();
textField.setHorizontalAlignment(SwingConstants.RIGHT);
getPanel().add(textField, BorderLayout.CENTER);
textField.setColumns(10);
textField.setBorder(null);
textField.setOpaque(false);
textField.setBackground(new Color(0,0,0,0));
label.setForeground(Color.GRAY);
button = new JButton();
getPanel().add(button, BorderLayout.EAST);
button.setFont(button.getFont());
//button.setBorder(null);
//button.setOpaque(false);
button.setBackground(new Color(0,0,0,0));
}
}
@@ -0,0 +1,35 @@
package org.kne.cloud.klalb.uitool;
import java.awt.Color;
import java.awt.Font;
import javax.swing.JTextField;
import java.awt.BorderLayout;
import javax.swing.SwingConstants;
import org.kne.cloud.network.klalb.ui.UIEnv;
public class TextSettingItem extends SettingItem {
protected JTextField textField;
public JTextField getTextField() {
return textField;
}
public TextSettingItem(String text,int w,int h) {
this(text,UIEnv.getFont().deriveFont((float) 15.0),w,h);
}
/**
* @wbp.parser.constructor
*/
public TextSettingItem(String text, Font deriveFont,int w,int h) {
super(text,deriveFont,w,h);
textField = new JTextField();
textField.setHorizontalAlignment(SwingConstants.RIGHT);
getPanel().add(textField, BorderLayout.CENTER);
textField.setColumns(10);
textField.setBorder(null);
textField.setOpaque(false);
textField.setBackground(new Color(0,0,0,0));
label.setForeground(Color.GRAY);
}
}
@@ -0,0 +1,233 @@
/*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.kne.cloud.klalb.uitool;
import javax.swing.ListModel;
import javax.swing.event.*;
import java.io.Serializable;
import java.util.EventListener;
/**
* The abstract definition for the data model that provides
* a <code>List</code> with its contents.
* <p>
* <strong>Warning:</strong>
* Serialized objects of this class will not be compatible with
* future Swing releases. The current serialization support is
* appropriate for short term storage or RMI between applications running
* the same version of Swing. As of 1.4, support for long term storage
* of all JavaBeans
* has been added to the <code>java.beans</code> package.
* Please see {@link java.beans.XMLEncoder}.
*
* @param <E> the type of the elements of this model
*
* @author Hans Muller
* @since 1.2
*/
@SuppressWarnings("serial") // Same-version serialization only
public abstract class XAbstractListModel<E> implements ListModel<E>, Serializable
{
/**
* The listener list.
*/
protected EventListenerList listenerList = new EventListenerList();
/**
* Constructor for subclasses to call.
*/
protected XAbstractListModel() {}
/**
* Adds a listener to the list that's notified each time a change
* to the data model occurs.
*
* @param l the <code>ListDataListener</code> to be added
*/
public void addListDataListener(ListDataListener l) {
listenerList.add(ListDataListener.class, l);
}
/**
* Removes a listener from the list that's notified each time a
* change to the data model occurs.
*
* @param l the <code>ListDataListener</code> to be removed
*/
public void removeListDataListener(ListDataListener l) {
listenerList.remove(ListDataListener.class, l);
}
/**
* Returns an array of all the list data listeners
* registered on this <code>AbstractListModel</code>.
*
* @return all of this model's <code>ListDataListener</code>s,
* or an empty array if no list data listeners
* are currently registered
*
* @see #addListDataListener
* @see #removeListDataListener
*
* @since 1.4
*/
public ListDataListener[] getListDataListeners() {
return listenerList.getListeners(ListDataListener.class);
}
/**
* <code>AbstractListModel</code> subclasses must call this method
* <b>after</b>
* one or more elements of the list change. The changed elements
* are specified by the closed interval index0, index1 -- the endpoints
* are included. Note that
* index0 need not be less than or equal to index1.
*
* @param source the <code>ListModel</code> that changed, typically "this"
* @param index0 one end of the new interval
* @param index1 the other end of the new interval
* @see EventListenerList
* @see XDefaultListModel
*/
protected void fireContentsChanged(Object source, int index0, int index1)
{
Object[] listeners = listenerList.getListenerList();
ListDataEvent e = null;
for (int i = listeners.length - 2; i >= 0; i -= 2) {
if (listeners[i] == ListDataListener.class) {
if (e == null) {
e = new ListDataEvent(source, ListDataEvent.CONTENTS_CHANGED, index0, index1);
}
((ListDataListener)listeners[i+1]).contentsChanged(e);
}
}
}
/**
* <code>AbstractListModel</code> subclasses must call this method
* <b>after</b>
* one or more elements are added to the model. The new elements
* are specified by a closed interval index0, index1 -- the enpoints
* are included. Note that
* index0 need not be less than or equal to index1.
*
* @param source the <code>ListModel</code> that changed, typically "this"
* @param index0 one end of the new interval
* @param index1 the other end of the new interval
* @see EventListenerList
* @see XDefaultListModel
*/
protected void fireIntervalAdded(Object source, int index0, int index1)
{
Object[] listeners = listenerList.getListenerList();
ListDataEvent e = null;
for (int i = listeners.length - 2; i >= 0; i -= 2) {
if (listeners[i] == ListDataListener.class) {
if (e == null) {
e = new ListDataEvent(source, ListDataEvent.INTERVAL_ADDED, index0, index1);
}
((ListDataListener)listeners[i+1]).intervalAdded(e);
}
}
}
/**
* <code>AbstractListModel</code> subclasses must call this method
* <b>after</b> one or more elements are removed from the model.
* <code>index0</code> and <code>index1</code> are the end points
* of the interval that's been removed. Note that <code>index0</code>
* need not be less than or equal to <code>index1</code>.
*
* @param source the <code>ListModel</code> that changed, typically "this"
* @param index0 one end of the removed interval,
* including <code>index0</code>
* @param index1 the other end of the removed interval,
* including <code>index1</code>
* @see EventListenerList
* @see XDefaultListModel
*/
protected void fireIntervalRemoved(Object source, int index0, int index1)
{
Object[] listeners = listenerList.getListenerList();
ListDataEvent e = null;
for (int i = listeners.length - 2; i >= 0; i -= 2) {
if (listeners[i] == ListDataListener.class) {
if (e == null) {
e = new ListDataEvent(source, ListDataEvent.INTERVAL_REMOVED, index0, index1);
}
((ListDataListener)listeners[i+1]).intervalRemoved(e);
}
}
}
/**
* Returns an array of all the objects currently registered as
* <code><em>Foo</em>Listener</code>s
* upon this model.
* <code><em>Foo</em>Listener</code>s
* are registered using the <code>add<em>Foo</em>Listener</code> method.
* <p>
* You can specify the <code>listenerType</code> argument
* with a class literal, such as <code><em>Foo</em>Listener.class</code>.
* For example, you can query a list model
* <code>m</code>
* for its list data listeners
* with the following code:
*
* <pre>ListDataListener[] ldls = (ListDataListener[])(m.getListeners(ListDataListener.class));</pre>
*
* If no such listeners exist,
* this method returns an empty array.
*
* @param <T> the type of {@code EventListener} class being requested
* @param listenerType the type of listeners requested;
* this parameter should specify an interface
* that descends from <code>java.util.EventListener</code>
* @return an array of all objects registered as
* <code><em>Foo</em>Listener</code>s
* on this model,
* or an empty array if no such
* listeners have been added
* @exception ClassCastException if <code>listenerType</code> doesn't
* specify a class or interface that implements
* <code>java.util.EventListener</code>
*
* @see #getListDataListeners
*
* @since 1.3
*/
public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
return listenerList.getListeners(listenerType);
}
}
@@ -0,0 +1,46 @@
package org.kne.cloud.klalb.uitool;
import java.awt.Graphics;
import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.JButton;
public class XButton extends JButton{
/**
*
*/
public XButton() {
super();
super.setContentAreaFilled(false);
}
public XButton(Action a) {
super(a);
super.setContentAreaFilled(false);
}
public XButton(Icon icon) {
super(icon);
super.setContentAreaFilled(false);
}
public XButton(String text, Icon icon) {
super(text, icon);
super.setContentAreaFilled(false);
}
public XButton(String text) {
super(text);
super.setContentAreaFilled(false);
}
@Override
public void paint(Graphics g) {
g.setColor(getBackground());
g.fillRoundRect(0, 0, getWidth()-1, getHeight()-1, 20, 20);
super.paint(g);
}
}
@@ -0,0 +1,584 @@
/*
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.kne.cloud.klalb.uitool;
import java.util.Vector;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.Collection;
import java.util.Enumeration;
/**
* This class loosely implements the {@code java.util.Vector}
* API, in that it implements the 1.1.x version of
* {@code java.util.Vector}, has no collection class support,
* and notifies the {@code ListDataListener}s when changes occur.
* Presently it delegates to a {@code Vector},
* in a future release it will be a real Collection implementation.
* <p>
* <strong>Warning:</strong>
* Serialized objects of this class will not be compatible with
* future Swing releases. The current serialization support is
* appropriate for short term storage or RMI between applications running
* the same version of Swing. As of 1.4, support for long term storage
* of all JavaBeans
* has been added to the {@code java.beans} package.
* Please see {@link java.beans.XMLEncoder}.
*
* @param <E> the type of the elements of this model
*
* @author Hans Muller
* @since 1.2
*/
@SuppressWarnings("serial") // Same-version serialization only
public class XDefaultListModel<E> extends XAbstractListModel<E> implements Externalizable
{
private Vector<E> delegate = new Vector<E>();
/**
* Constructs a {@code DefaultListModel}.
*/
public XDefaultListModel() {}
/**
* Returns the number of components in this list.
* <p>
* This method is identical to {@code size}, which implements the
* {@code List} interface defined in the 1.2 Collections framework.
* This method exists in conjunction with {@code setSize} so that
* {@code size} is identifiable as a JavaBean property.
*
* @return the number of components in this list
* @see #size()
*/
public int getSize() {
return delegate.size();
}
/**
* Returns the component at the specified index.
* <blockquote>
* <b>Note:</b> Although this method is not deprecated, the preferred
* method to use is {@code get(int)}, which implements the {@code List}
* interface defined in the 1.2 Collections framework.
* </blockquote>
* @param index an index into this list
* @return the component at the specified index
* @throws ArrayIndexOutOfBoundsException if the {@code index}
* is negative or greater than the current size of this
* list
* @see #get(int)
*/
public E getElementAt(int index) {
return delegate.elementAt(index);
}
/**
* Copies the components of this list into the specified array.
* The array must be big enough to hold all the objects in this list,
* else an {@code IndexOutOfBoundsException} is thrown.
*
* @param anArray the array into which the components get copied
* @see Vector#copyInto(Object[])
*/
public void copyInto(Object[] anArray) {
delegate.copyInto(anArray);
}
/**
* Trims the capacity of this list to be the list's current size.
*
* @see Vector#trimToSize()
*/
public void trimToSize() {
delegate.trimToSize();
}
/**
* Increases the capacity of this list, if necessary, to ensure
* that it can hold at least the number of components specified by
* the minimum capacity argument.
*
* @param minCapacity the desired minimum capacity
* @see Vector#ensureCapacity(int)
*/
public void ensureCapacity(int minCapacity) {
delegate.ensureCapacity(minCapacity);
}
/**
* Sets the size of this list.
*
* @param newSize the new size of this list
* @see Vector#setSize(int)
*/
public void setSize(int newSize) {
int oldSize = delegate.size();
delegate.setSize(newSize);
if (oldSize > newSize) {
fireIntervalRemoved(this, newSize, oldSize-1);
}
else if (oldSize < newSize) {
fireIntervalAdded(this, oldSize, newSize-1);
}
}
/**
* Returns the current capacity of this list.
*
* @return the current capacity
* @see Vector#capacity()
*/
public int capacity() {
return delegate.capacity();
}
/**
* Returns the number of components in this list.
*
* @return the number of components in this list
* @see Vector#size()
*/
public int size() {
return delegate.size();
}
/**
* Tests whether this list has any components.
*
* @return {@code true} if and only if this list has
* no components, that is, its size is zero;
* {@code false} otherwise
* @see Vector#isEmpty()
*/
public boolean isEmpty() {
return delegate.isEmpty();
}
/**
* Returns an enumeration of the components of this list.
*
* @return an enumeration of the components of this list
* @see Vector#elements()
*/
public Enumeration<E> elements() {
return delegate.elements();
}
/**
* Tests whether the specified object is a component in this list.
*
* @param elem an object
* @return {@code true} if the specified object
* is the same as a component in this list
* @see Vector#contains(Object)
*/
public boolean contains(Object elem) {
return delegate.contains(elem);
}
/**
* Searches for the first occurrence of {@code elem}.
*
* @param elem an object
* @return the index of the first occurrence of the argument in this
* list; returns {@code -1} if the object is not found
* @see Vector#indexOf(Object)
*/
public int indexOf(Object elem) {
return delegate.indexOf(elem);
}
/**
* Searches for the first occurrence of {@code elem}, beginning
* the search at {@code index}.
*
* @param elem the desired component
* @param index the index from which to begin searching
* @return the index where the first occurrence of {@code elem}
* is found after {@code index}; returns {@code -1}
* if the {@code elem} is not found in the list
* @see Vector#indexOf(Object,int)
*/
public int indexOf(Object elem, int index) {
return delegate.indexOf(elem, index);
}
/**
* Returns the index of the last occurrence of {@code elem}.
*
* @param elem the desired component
* @return the index of the last occurrence of {@code elem}
* in the list; returns {@code elem} if the object is not found
* @see Vector#lastIndexOf(Object)
*/
public int lastIndexOf(Object elem) {
return delegate.lastIndexOf(elem);
}
/**
* Searches backwards for {@code elem}, starting from the
* specified index, and returns an index to it.
*
* @param elem the desired component
* @param index the index to start searching from
* @return the index of the last occurrence of the {@code elem}
* in this list at position less than {@code index};
* returns {@code -1} if the object is not found
* @see Vector#lastIndexOf(Object,int)
*/
public int lastIndexOf(Object elem, int index) {
return delegate.lastIndexOf(elem, index);
}
/**
* Returns the component at the specified index.
* <blockquote>
* <b>Note:</b> Although this method is not deprecated, the preferred
* method to use is {@code get(int)}, which implements the
* {@code List} interface defined in the 1.2 Collections framework.
* </blockquote>
*
* @param index an index into this list
* @return the component at the specified index
* @throws ArrayIndexOutOfBoundsException if the index
* is negative or not less than the size of the list
* @see #get(int)
* @see Vector#elementAt(int)
*/
public E elementAt(int index) {
return delegate.elementAt(index);
}
/**
* Returns the first component of this list.
* @return the first component of this list
* @see Vector#firstElement()
* @throws java.util.NoSuchElementException if this
* vector has no components
*/
public E firstElement() {
return delegate.firstElement();
}
/**
* Returns the last component of the list.
*
* @return the last component of the list
* @see Vector#lastElement()
* @throws java.util.NoSuchElementException if this vector
* has no components
*/
public E lastElement() {
return delegate.lastElement();
}
/**
* Sets the component at the specified {@code index} of this
* list to be the specified element. The previous component at that
* position is discarded.
* <blockquote>
* <b>Note:</b> Although this method is not deprecated, the preferred
* method to use is {@code set(int,Object)}, which implements the
* {@code List} interface defined in the 1.2 Collections framework.
* </blockquote>
*
* @param element what the component is to be set to
* @param index the specified index
* @throws ArrayIndexOutOfBoundsException if the index is invalid
* @see #set(int,Object)
* @see Vector#setElementAt(Object,int)
*/
public void setElementAt(E element, int index) {
delegate.setElementAt(element, index);
fireContentsChanged(this, index, index);
}
/**
* Deletes the component at the specified index.
* <blockquote>
* <b>Note:</b> Although this method is not deprecated, the preferred
* method to use is {@code remove(int)}, which implements the
* {@code List} interface defined in the 1.2 Collections framework.
* </blockquote>
*
* @param index the index of the object to remove
* @see #remove(int)
* @see Vector#removeElementAt(int)
* @throws ArrayIndexOutOfBoundsException if the index is invalid
*/
public void removeElementAt(int index) {
delegate.removeElementAt(index);
fireIntervalRemoved(this, index, index);
}
/**
* Inserts the specified element as a component in this list at the
* specified <code>index</code>.
* <blockquote>
* <b>Note:</b> Although this method is not deprecated, the preferred
* method to use is {@code add(int,Object)}, which implements the
* {@code List} interface defined in the 1.2 Collections framework.
* </blockquote>
*
* @param element the component to insert
* @param index where to insert the new component
* @exception ArrayIndexOutOfBoundsException if the index was invalid
* @see #add(int,Object)
* @see Vector#insertElementAt(Object,int)
*/
public void insertElementAt(E element, int index) {
delegate.insertElementAt(element, index);
fireIntervalAdded(this, index, index);
}
/**
* Adds the specified component to the end of this list.
*
* @param element the component to be added
* @see Vector#addElement(Object)
*/
public void addElement(E element) {
int index = delegate.size();
delegate.addElement(element);
fireIntervalAdded(this, index, index);
}
/**
* Removes the first (lowest-indexed) occurrence of the argument
* from this list.
*
* @param obj the component to be removed
* @return {@code true} if the argument was a component of this
* list; {@code false} otherwise
* @see Vector#removeElement(Object)
*/
public boolean removeElement(Object obj) {
int index = indexOf(obj);
boolean rv = delegate.removeElement(obj);
if (index >= 0) {
fireIntervalRemoved(this, index, index);
}
return rv;
}
/**
* Removes all components from this list and sets its size to zero.
* <blockquote>
* <b>Note:</b> Although this method is not deprecated, the preferred
* method to use is {@code clear}, which implements the
* {@code List} interface defined in the 1.2 Collections framework.
* </blockquote>
*
* @see #clear()
* @see Vector#removeAllElements()
*/
public void removeAllElements() {
int index1 = delegate.size()-1;
delegate.removeAllElements();
if (index1 >= 0) {
fireIntervalRemoved(this, 0, index1);
}
}
/**
* Returns a string that displays and identifies this
* object's properties.
*
* @return a String representation of this object
*/
public String toString() {
return delegate.toString();
}
/* The remaining methods are included for compatibility with the
* Java 2 platform Vector class.
*/
/**
* Returns an array containing all of the elements in this list in the
* correct order.
*
* @return an array containing the elements of the list
* @see Vector#toArray()
*/
public Object[] toArray() {
Object[] rv = new Object[delegate.size()];
delegate.copyInto(rv);
return rv;
}
/**
* Returns the element at the specified position in this list.
*
* @param index index of element to return
* @return the element at the specified position in this list
* @throws ArrayIndexOutOfBoundsException if the index is out of range
* ({@code index &lt; 0 || index &gt;= size()})
*/
public E get(int index) {
return delegate.elementAt(index);
}
/**
* Replaces the element at the specified position in this list with the
* specified element.
*
* @param index index of element to replace
* @param element element to be stored at the specified position
* @return the element previously at the specified position
* @throws ArrayIndexOutOfBoundsException if the index is out of range
* ({@code index &lt; 0 || index &gt;= size()})
*/
public E set(int index, E element) {
E rv = delegate.elementAt(index);
delegate.setElementAt(element, index);
fireContentsChanged(this, index, index);
return rv;
}
/**
* Inserts the specified element at the specified position in this list.
*
* @param index index at which the specified element is to be inserted
* @param element element to be inserted
* @throws ArrayIndexOutOfBoundsException if the index is out of range
* ({@code index &lt; 0 || index &gt; size()})
*/
public void add(int index, E element) {
delegate.insertElementAt(element, index);
fireIntervalAdded(this, index, index);
}
/**
* Removes the element at the specified position in this list.
* Returns the element that was removed from the list
*
* @param index the index of the element to removed
* @return the element previously at the specified position
* @throws ArrayIndexOutOfBoundsException if the index is out of range
* ({@code index &lt; 0 || index &gt;= size()})
*/
public E remove(int index) {
E rv = delegate.elementAt(index);
delegate.removeElementAt(index);
fireIntervalRemoved(this, index, index);
return rv;
}
/**
* Removes all of the elements from this list. The list will
* be empty after this call returns (unless it throws an exception).
*/
public void clear() {
int index1 = delegate.size()-1;
delegate.removeAllElements();
if (index1 >= 0) {
fireIntervalRemoved(this, 0, index1);
}
}
/**
* Deletes the components at the specified range of indexes.
* The removal is inclusive, so specifying a range of (1,5)
* removes the component at index 1 and the component at index 5,
* as well as all components in between.
*
* @param fromIndex the index of the lower end of the range
* @param toIndex the index of the upper end of the range
* @throws ArrayIndexOutOfBoundsException if the index was invalid
* @throws IllegalArgumentException if {@code fromIndex &gt; toIndex}
* @see #remove(int)
*/
public void removeRange(int fromIndex, int toIndex) {
if (fromIndex > toIndex) {
throw new IllegalArgumentException("fromIndex must be <= toIndex");
}
for(int i = toIndex; i >= fromIndex; i--) {
delegate.removeElementAt(i);
}
fireIntervalRemoved(this, fromIndex, toIndex);
}
/**
* Adds all of the elements present in the collection to the list.
*
* @param c the collection which contains the elements to add
* @throws NullPointerException if {@code c} is null
*/
public void addAll(Collection<? extends E> c) {
if (c.isEmpty()) {
return;
}
int startIndex = getSize();
delegate.addAll(c);
fireIntervalAdded(this, startIndex, getSize() - 1);
}
/**
* Adds all of the elements present in the collection, starting
* from the specified index.
*
* @param index index at which to insert the first element from the
* specified collection
* @param c the collection which contains the elements to add
* @throws ArrayIndexOutOfBoundsException if {@code index} does not
* fall within the range of number of elements currently held
* @throws NullPointerException if {@code c} is null
*/
public void addAll(int index, Collection<? extends E> c) {
if (index < 0 || index > getSize()) {
throw new ArrayIndexOutOfBoundsException("index out of range: " +
index);
}
if (c.isEmpty()) {
return;
}
delegate.addAll(index, c);
fireIntervalAdded(this, index, index + c.size() - 1);
}
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject(delegate);
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
delegate=(Vector<E>) in.readObject();
}
}
@@ -0,0 +1,396 @@
package org.kne.cloud.network;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.ReentrantLock;
/**
* 修复的BufferedChannel,解决Socket关闭时的数据一致性问题
*/
public class BufferedChannel implements ReadableByteChannel, WritableByteChannel, ScatteringByteChannel, GatheringByteChannel {
private final ReadableByteChannel inputChannel;
private final WritableByteChannel outputChannel;
private final ByteBuffer readBuffer;
private final ByteBuffer writeBuffer;
// private final AtomicBoolean closed = new AtomicBoolean(false);
private final AtomicBoolean inputShutdown = new AtomicBoolean(false);
private final AtomicBoolean outputShutdown = new AtomicBoolean(false);
public BufferedChannel(ReadableByteChannel channel, int bufferSize) {
this(channel, null, bufferSize);
}
public BufferedChannel(WritableByteChannel channel, int bufferSize) {
this(null, channel, bufferSize);
}
public BufferedChannel(ReadableByteChannel inputChannel, WritableByteChannel outputChannel, int bufferSize) {
this.inputChannel = inputChannel;
this.outputChannel = outputChannel;
this.readBuffer = ByteBuffer.allocateDirect(bufferSize);
this.writeBuffer = ByteBuffer.allocateDirect(bufferSize);
// 更安全的初始化
this.readBuffer.limit(0); // 明确设置为空
this.writeBuffer.clear();
}
@Override
public int read(ByteBuffer dst) throws IOException {
if ( inputShutdown.get()) {
throw new ClosedChannelException();
}
// 检查底层通道是否仍然打开
if (inputChannel != null && !inputChannel.isOpen()) {
inputShutdown.set(true);
return handleInputShutdown();
}
int totalRead = 0;
boolean eofEncountered = false;
while (dst.hasRemaining() && !eofEncountered) {
// 如果读缓冲区有数据,先从中读取
if (readBuffer.hasRemaining()) {
int bytesToCopy = Math.min(readBuffer.remaining(), dst.remaining());
// 使用绝对位置操作,避免修改缓冲区状态
int oldlimit=readBuffer.limit();
readBuffer.limit(readBuffer.position()+bytesToCopy);
dst.put(readBuffer);
readBuffer.limit(oldlimit);
totalRead += bytesToCopy;
continue;
}
// 读缓冲区空了,需要重新填充
readBuffer.clear();
int bytesRead;
try {
bytesRead = inputChannel.read(readBuffer);
} catch (IOException e) {
// 读取时发生IO异常,标记为关闭
inputShutdown.set(true);
throw e;
}
if (bytesRead == -1) {
// 到达EOF
inputShutdown.set(true);
eofEncountered = true;
} else if (bytesRead == 0) {
// 没有数据可用,可能是非阻塞模式
break;
} else {
readBuffer.flip();
}
}
// 如果遇到EOF且没有读取到任何数据,返回-1
if (eofEncountered && totalRead == 0) {
return -1;
}
return totalRead;
}
/**
* 处理输入关闭的情况
*/
private int handleInputShutdown() throws IOException {
// 如果读缓冲区还有剩余数据,先返回这些数据
if (readBuffer.hasRemaining()) {
return readBuffer.remaining();
}
return -1;
}
@Override
public long read(ByteBuffer[] dsts) throws IOException {
return read(dsts, 0, dsts.length);
}
@Override
public long read(ByteBuffer[] dsts, int offset, int length) throws IOException {
long totalRead = 0;
for (int i = offset; i < offset + length; i++) {
ByteBuffer dst = dsts[i];
if (dst == null) {
throw new NullPointerException("Destination buffer is null");
}
int bytesRead = read(dst);
if (bytesRead == -1) {
// 只有在没有读取任何数据时才返回-1
return totalRead > 0 ? totalRead : -1;
}
totalRead += bytesRead;
}
return totalRead;
}
@Override
public int write(ByteBuffer src) throws IOException {
// 检查底层通道是否仍然打开
if (outputChannel != null && !outputChannel.isOpen()) {
outputShutdown.set(true);
throw new ClosedChannelException();
}
int totalWritten = 0;
while (src.hasRemaining()) {
// 如果写缓冲区有空间,先填充
if (writeBuffer.hasRemaining()) {
int bytesToCopy = Math.min(writeBuffer.remaining(), src.remaining());
int oldlimit= src.limit();
src.limit(src.position()+bytesToCopy);
writeBuffer.put(src);
src.limit(oldlimit);
totalWritten += bytesToCopy;
}
// 如果写缓冲区满了或者源数据还很多,刷新缓冲区
if (!writeBuffer.hasRemaining() ) {
try {
flushInternal();
} catch (IOException e) {
outputShutdown.set(true);
throw e;
}
}
}
return totalWritten;
}
@Override
public long write(ByteBuffer[] srcs) throws IOException {
return write(srcs, 0, srcs.length);
}
@Override
public long write(ByteBuffer[] srcs, int offset, int length) throws IOException {
long totalWritten = 0;
for (int i = offset; i < offset + length; i++) {
ByteBuffer src = srcs[i];
if (src == null) {
throw new NullPointerException("Source buffer is null");
}
int bytesWritten = write(src);
totalWritten += bytesWritten;
}
return totalWritten;
}
/**
* 安全的刷新方法
*/
public void flush() throws IOException {
if (outputChannel == null || outputShutdown.get()) {
return;
}
try {
flushInternal();
} catch (IOException e) {
outputShutdown.set(true);
throw e;
}
}
/**
* 内部刷新方法,假设已经持有writeLock
*/
private void flushInternal() throws IOException {
if (writeBuffer.position() > 0) {
writeBuffer.flip();
try {
while (writeBuffer.hasRemaining()) {
int written = outputChannel.write(writeBuffer);
// System.out.println("发送"+written);
if (written == 0) {
// 可能遇到阻塞或关闭
if (!outputChannel.isOpen()) {
outputShutdown.set(true);
throw new ClosedChannelException();
}
// 给其他操作机会
Thread.yield();
}
}
} finally {
// 无论发生什么,确保写缓冲区处于可写状态
writeBuffer.clear();
}
}
}
/**
* 安全的关闭方法
*/
@Override
public void close() throws IOException {
IOException exception = null;
// 先刷新输出缓冲区
if (outputChannel != null && !outputShutdown.get()) {
if (writeBuffer.position() > 0) {
try {
flushInternal();
} catch (IOException e) {
exception = e;
}
}
}
// 关闭底层通道
try {
if (inputChannel != null) {
inputChannel.close();
}
} catch (IOException e) {
if (exception == null) {
exception = e;
} else {
exception.addSuppressed(e);
}
}
try {
if (outputChannel != null) {
outputChannel.close();
}
} catch (IOException e) {
if (exception == null) {
exception = e;
} else {
exception.addSuppressed(e);
}
}
// 清理缓冲区状态
readBuffer.clear();
readBuffer.limit(0); // 标记为已清空
writeBuffer.clear();
// 设置关闭状态
inputShutdown.set(true);
outputShutdown.set(true);
if (exception != null) {
throw exception;
}
}
/**
* 优雅关闭 - 只关闭输入或输出
*/
public void shutdownInput() throws IOException {
inputShutdown.set(true);
readBuffer.clear();
readBuffer.limit(0);
if (inputChannel instanceof SocketChannel) {
((SocketChannel) inputChannel).shutdownInput();
}
}
public void shutdownOutput() throws IOException {
outputShutdown.set(true);
if (writeBuffer.position() > 0) {
flushInternal();
}
if (outputChannel instanceof SocketChannel) {
((SocketChannel) outputChannel).shutdownOutput();
}
}
@Override
public boolean isOpen() {
return
(inputChannel == null || inputChannel.isOpen()) &&
(outputChannel == null || outputChannel.isOpen());
}
/**
* 检查是否还有可读数据(包括缓冲区中的)
*/
public boolean hasRemaining() throws IOException {
if ( inputShutdown.get()) {
return false;
}
return readBuffer.hasRemaining() ||
(inputChannel != null && inputChannel.isOpen());
}
/**
* 获取缓冲区状态信息(用于调试)
*/
public String getBufferState() {
return String.format(
"ReadBuffer[pos=%d, lim=%d, cap=%d], WriteBuffer[pos=%d, lim=%d, cap=%d], " +
"closed=%b, inputShutdown=%b, outputShutdown=%b",
readBuffer.position(), readBuffer.limit(), readBuffer.capacity(),
writeBuffer.position(), writeBuffer.limit(), writeBuffer.capacity(), inputShutdown.get(), outputShutdown.get()
);
}
// 其他方法保持不变...
public int available() throws IOException {
if ( inputShutdown.get()) {
return 0;
}
return readBuffer.remaining();
}
public long skip(long n) throws IOException {
// 实现保持不变...
return 0;
}
}
@@ -0,0 +1,36 @@
package org.kne.cloud.network;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ConcurrentLinkedQueue;
public class ByteArrayPool {
private Queue<byte[]> rec;
private int maxcount;
private int length;
public ByteArrayPool(int maxcount, int length) {
super();
this.maxcount = maxcount;
this.length = length;
rec=new ConcurrentLinkedQueue<byte[]>();
}
public void back(byte[]b) {
if(b.length!=length)
throw new IllegalArgumentException("wrong length");
rec.offer(b);
}
public byte[] borrow() {
byte[]b=rec.poll();
if(b==null) {
b=new byte[length];
}
return b;
}
public int getMaxCount() {
return maxcount;
}
public int getLength() {
return length;
}
}
@@ -0,0 +1,41 @@
package org.kne.cloud.network;
import java.lang.foreign.Arena;
import java.nio.ByteBuffer;
import org.kne.membandboost.MembandBoost;
public class ByteBufferAllocator {
public ByteBufferAllocator(boolean isDirect) {
}
public ByteBuffer allocate(int capacity) {
//if(capacity<1024)
return allocateHeap(capacity);
// return allocateNative(capacity);
}
//private Arena ar=BufferedArena.ofBuffered();
//private Arena ara=Arena.ofAuto();
public ByteBuffer allocateNative(int capacity) {
//return ((jdk.internal.foreign.ArenaImpl)ara).allocateNoInit(capacity,1).asByteBuffer();
ByteBuffer buf=Arena.ofAuto().allocate(capacity).asByteBuffer();
if(buf.capacity()!=capacity)
throw new InternalError();
return buf;
}
public static ByteBuffer allocateHeap(int capacity) {
/*if(capacity<=2048) {
return MembandBoost.allocateUninitializedHeapBufferBlocked(capacity);
}else {*/
return MembandBoost.allocateUninitializedHeapBuffer(capacity);
//}
}
}
@@ -0,0 +1,79 @@
package org.kne.cloud.network;
import java.nio.ByteBuffer;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReferenceArray;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.kne.concurrent.SpinLock;
import org.kne.debug.TimeDebugger;
public class ByteBufferPool {
private AtomicReferenceArray< ByteBuffer> rec;
private volatile AtomicInteger pos=new AtomicInteger( 0);
//private Lock lock=new SpinLock();
private int maxcount;
private int length;
private int mcj;
private boolean direct;
public ByteBufferPool(int maxcount, int length,boolean direct) {
super();
this.maxcount = maxcount;
this.length = length;
this.direct=direct;
rec=new AtomicReferenceArray<ByteBuffer>(maxcount);
mcj= rec.length()-1;
}
public ByteBufferPool(int maxcount, int length) {
this(maxcount, length, true);
}
public void back(ByteBuffer b) {
if(b.capacity()!=length)
throw new IllegalArgumentException("wrong length");
b.clear();
if(pos.get()<=mcj) {
int d=pos.getAndIncrement();
if(d>mcj)
d=mcj;
if(d<0)
d=0;
rec.compareAndSet(d,null,b);
}
}
public ByteBuffer borrow() {
ByteBuffer b=null;
if(pos.get()>0) {
int d=pos.decrementAndGet();
if(d>mcj)
d=mcj;
if(d<0)
d=0;
b=rec.getAndSet(d,null);
}
if(b==null) {
if(direct)
b=ByteBuffer.allocateDirect(length);
else
b=ByteBuffer.allocate(length);
}
return b;
}
public int getMaxCount() {
return maxcount;
}
public int getLength() {
return length;
}
}
@@ -0,0 +1,92 @@
package org.kne.cloud.network;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.util.Objects;
import java.util.UUID;
import org.kne.io.Task;
public class ChannelBridge extends Task{
protected ReadableByteChannel in;
protected WritableByteChannel out;
protected int blocksize=65535;
protected long delay=0;
public ChannelBridge(ReadableByteChannel in, WritableByteChannel out) {
super();
Objects.requireNonNull(in);
Objects.requireNonNull(out);
this.in = in;
this.out = out;
}
@Override
public void runTask() {
//FileOutputStream fos=null;
try {
//fos=new FileOutputStream(UUID.randomUUID()+".txt");
ByteBuffer b=ByteBuffer.allocateDirect(blocksize);
while (in.read(b)!=-1) {
b.flip();
out.write(b);
b.clear();
if(delay>0) {
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
e.printStackTrace();
}
}else {
Thread.yield();
}
}
} catch (IOException e) {
e.printStackTrace();
}finally {
/*if(fos!=null)
try {
fos.close();
} catch (IOException e1) {
e1.printStackTrace();
}*/
try {
if(in!=null)
in.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if(in!=null)
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public int getBlocksize() {
return blocksize;
}
public void setBlocksize(int blocksize) {
this.blocksize = blocksize;
}
public long getDelay() {
return delay;
}
public void setDelay(long delay) {
this.delay = delay;
}
public void runAtNewThread() {
runAtNewThread("StreamBridge thread");
}
public Thread runAtNewThread(String name) {
Thread t=ThreadTool.makeVThreadIfSupport(name, this);
t.start();
return t;
}
}
@@ -0,0 +1,359 @@
package org.kne.cloud.network;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.LockSupport;
public class DatagramServerSocket implements java.io.Closeable{
public static final ByteArrayPool dataarraypool=new ByteArrayPool(100, 65535);
private boolean closed=false;
private boolean bound=false;
private DatagramSocketFactory dgsf;
private Set<DatagramDistributor> skts=new HashSet<>();
private final Object stateLock = new Object();
private BlockingQueue<DatagramSocket> recs;
private InetSocketAddress bindpoint;
public DatagramServerSocket() throws SocketException {
this(new DefaultDatagramSocketFactory());
}
protected DatagramServerSocket(DatagramSocketFactory impl) throws SocketException {
this.dgsf=impl;
}
public DatagramServerSocket(int port, InetAddress laddr) throws SocketException {
this(new DefaultDatagramSocketFactory());
bind(new InetSocketAddress(laddr, port));
}
public DatagramServerSocket(int port) throws SocketException {
this(new DefaultDatagramSocketFactory());
bind(new InetSocketAddress(port));
}
public DatagramServerSocket(SocketAddress bindaddr) throws SocketException {
this(new DefaultDatagramSocketFactory());
bind(bindaddr);
}
public DatagramServerSocket(int port, int backlog) throws SocketException {
this(new DefaultDatagramSocketFactory());
bind(new InetSocketAddress(port));
}
public DatagramServerSocket(int port, int backlog, InetAddress laddr) throws SocketException {
this(new DefaultDatagramSocketFactory());
bind(new InetSocketAddress(laddr, port));
}
public void bind(SocketAddress endpoint) throws SocketException {
bind(endpoint, 50);
}
public void bind(SocketAddress endpoint, int backlog) throws SocketException {
if (isClosed())
throw new SocketException("Socket is closed");
if (isBound())
throw new SocketException("Already bound");
if (endpoint == null)
endpoint = new InetSocketAddress(0);
if (!(endpoint instanceof InetSocketAddress epoint))
throw new IllegalArgumentException("Unsupported address type");
if (epoint.isUnresolved())
throw new SocketException("Unresolved address");
if (backlog < 1)
backlog = 50;
synchronized (stateLock) {
if (closed)
throw new SocketException("Socket is closed");
if (bound)
throw new SocketException("Already bound");
bind0(epoint);
recs=new ArrayBlockingQueue<DatagramSocket>(backlog);
bound = true;
}
}
private void bind0(InetSocketAddress epoint) throws SocketException {
bindpoint=epoint;
if(epoint.getAddress().isAnyLocalAddress()) {
Enumeration<NetworkInterface>eu= NetworkInterface.getNetworkInterfaces();
while (eu.hasMoreElements()) {
NetworkInterface networkInterface = (NetworkInterface) eu.nextElement();
if(networkInterface.isUp()) {
//System.out.println(networkInterface+" "+networkInterface.isUp());
Enumeration<InetAddress>ei= networkInterface.getInetAddresses();
while (ei.hasMoreElements()) {
InetAddress inetAddress = (InetAddress) ei.nextElement();
DatagramDistributor dd=new DatagramDistributor(new InetSocketAddress(inetAddress, epoint.getPort()));
skts.add(dd);
}
}
}
}else {
DatagramDistributor dd=new DatagramDistributor(epoint);
skts.add(dd);
}
}
private class DatagramDistributor implements Runnable{
private Map<SocketAddress,SubDatagramSocket> clients=new ConcurrentHashMap<>();
private InetSocketAddress epoint;
private DatagramSocket datagramSocket;
public DatagramDistributor(InetSocketAddress epoint) throws SocketException {
this.epoint=epoint;
datagramSocket=new DatagramSocket(epoint);
ThreadTool.makeVDaemonThreadIfSupport("Datagram Distribute Thread", this).start();
}
public DatagramSocket getDatagramSocket() {
return datagramSocket;
}
@Override
public void run() {
try {
while(!closed) {
byte[]data=dataarraypool.borrow();
DatagramPacket dp=new DatagramPacket(data,data.length);
datagramSocket.receive(dp);
//System.out.println("get:"+dp);
SubDatagramSocket sdds=clients.get(dp.getSocketAddress());
if(sdds==null) {
if(recs.remainingCapacity()>1) {
sdds=new SubDatagramSocket(epoint, (InetSocketAddress) dp.getSocketAddress(),this );
if(recs.offer(sdds))
clients.put(dp.getSocketAddress(), sdds);
}
}
if(sdds!=null) {
//System.out.println("give:"+dp);
sdds.givePacket(dp);
}
}
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
public void removeClient(SubDatagramSocket subDatagramSocket) {
clients.remove(subDatagramSocket.getRemoteSocketAddress());
}
public void close() {
datagramSocket.close();
}
}
public DatagramSocket accept()throws IOException{
while(true) {
if(isClosed())
throw new SocketException("DatagramServerSocket closed");
if (!isBound())
throw new SocketException("DatagramServerSocket is not bound yet");
DatagramSocket sds= recs.poll();
if(sds!=null) {
return sds;
}
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private boolean isClosed() {
return closed;
}
private boolean isBound() {
return bound;
}
public class SubDatagramSocket extends DatagramSocket{
private DatagramDistributor parent;
private InetSocketAddress local;
private InetSocketAddress remote;
private boolean closed=false;
private int timeout=0;
private BlockingQueue<DatagramPacket> recs=new ArrayBlockingQueue(100);
private volatile Thread t;
private void unwait() {
if(t!=null)
LockSupport.unpark(t);
}
public SubDatagramSocket(InetSocketAddress local,InetSocketAddress remote,DatagramDistributor datagramDistributor) throws SocketException {
super((SocketAddress)null);
this.local=local;
this.remote=remote;
this.parent=datagramDistributor;
}
protected boolean givePacket(DatagramPacket dp) {
boolean b=recs.offer(dp);
unwait();
return b;
}
public DatagramPacket receive()throws IOException{
long start=System.nanoTime();
while(true) {
if(closed) {
throw new SocketException("DatagramSocket closed");
}
DatagramPacket dp=recs.poll();
if(dp!=null) {
return dp;
}
if(timeout!=0) {
long dms=(System.nanoTime()-start)/1000000;
if(dms>timeout)
throw new SocketTimeoutException("Receive Time Out");
}
t=Thread.currentThread();
LockSupport.parkNanos(1000000);
}
}
@Override
public void receive(DatagramPacket p) throws IOException {
DatagramPacket dp=null;
long start=System.nanoTime();
while(true) {
if(closed) {
throw new SocketException("DatagramSocket closed");
}
dp=recs.poll();
if(dp!=null) {
p.setLength(dp.getLength());
System.arraycopy(dp.getData(), dp.getOffset(), p.getData(), p.getOffset(), dp.getLength());
dataarraypool.back(dp.getData());
break;
}
if(timeout!=0) {
long dms=(System.nanoTime()-start)/1000000;
if(dms>timeout)
throw new SocketTimeoutException("Receive Time Out");
}
t=Thread.currentThread();
LockSupport.parkNanos(1000000);
}
}
@Override
public void send(DatagramPacket p) throws IOException {
p.setSocketAddress(remote);
parent.getDatagramSocket().send(p);
}
@Override
public SocketAddress getRemoteSocketAddress() {
return remote;
}
@Override
public InetAddress getInetAddress() {
return remote.getAddress();
}
@Override
public int getPort() {
return remote.getPort();
}
@Override
public SocketAddress getLocalSocketAddress() {
return local;
}
@Override
public InetAddress getLocalAddress() {
return local.getAddress();
}
@Override
public int getLocalPort() {
return local.getPort();
}
@Override
public void setSoTimeout(int timeout) throws SocketException {
this.timeout=timeout;
}
@Override
public int getSoTimeout() throws SocketException {
return timeout;
}
@Override
public void close() {
if(!closed)
parent.removeClient(this);
closed=true;
}
@Override
public boolean isClosed() {
return closed;
}
}
@Override
public void close() {
closed=true;
for (Iterator<DatagramDistributor> iterator = skts.iterator(); iterator.hasNext();) {
DatagramDistributor datagramSocket = (DatagramDistributor) iterator.next();
datagramSocket.close();
}
}
public SocketAddress getLocalSocketAddress() {
return bindpoint;
}
public InetAddress getLocalAddress() {
if(bindpoint==null)
return null;
else
return bindpoint.getAddress();
}
public int getLocalPort() {
if(bindpoint==null)
return -1;
else
return bindpoint.getPort();
}
}
@@ -0,0 +1,18 @@
package org.kne.cloud.network;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.SocketAddress;
public abstract class DatagramServerSocketFactory {
public DatagramServerSocket createDatagramServerSocket() throws IOException {
return new DatagramServerSocket((SocketAddress)null);
}
public abstract DatagramServerSocket createDatagramServerSocket(int port) throws IOException;
public abstract DatagramServerSocket createDatagramServerSocket(int port, int backlog) throws IOException;
public abstract DatagramServerSocket createDatagramServerSocket(int port, int backlog, InetAddress ifAddress) throws IOException;
}

Some files were not shown because too many files have changed in this diff Show More