Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
J
jk-test
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Container Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wuyuhang
jk-test
Commits
141d1b58
Commit
141d1b58
authored
Nov 09, 2026
by
wuyuhang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
更新网卡自动选择功能
parent
28909bda
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
115 additions
and
73 deletions
+115
-73
AppProperties.java
src/main/java/com/monitor/d2d/config/AppProperties.java
+21
-21
NetworkInterfaceSelector.java
.../java/com/monitor/d2d/netty/NetworkInterfaceSelector.java
+64
-0
UdpReceiver.java
src/main/java/com/monitor/d2d/netty/UdpReceiver.java
+4
-30
UdpSender.java
src/main/java/com/monitor/d2d/netty/UdpSender.java
+7
-3
ApiController.java
src/main/java/com/monitor/d2d/service/ApiController.java
+19
-19
No files found.
src/main/java/com/monitor/d2d/config/AppProperties.java
View file @
141d1b58
...
...
@@ -10,33 +10,33 @@ import org.springframework.stereotype.Component;
public
class
AppProperties
{
/** 监控软件信源地址 SID(十六进制,如 11651101) */
//
private String sid = "11651101";
//
// /** 数传软件信宿地址 DID(十六进制,如 26000004) */
//
private String did = "26000004";
//
// /** 命令发送目标组播地址 */
//
private String sendHost = "238.1.0.103";
//
// /** 命令发送目标端口 */
//
private int sendPort = 8889;
//
// /** 上报接收监听组播组 */
//
private String recvGroup = "238.1.0.3";
//
// /** 上报接收监听端口 */
//
private int recvPort = 8888;
private
String
sid
=
"11651101"
;
//** 数传软件信宿地址 DID(十六进制,如 26000004) *//*
private
String
did
=
"26000004"
;
//** 命令发送目标组播地址 *//*
private
String
sendHost
=
"238.1.0.103"
;
//** 命令发送目标端口 *//*
private
int
sendPort
=
8889
;
//** 上报接收监听组播组 *//*
private
String
recvGroup
=
"238.1.0.3"
;
//** 上报接收监听端口 *//*
private
int
recvPort
=
8888
;
// 244
private
String
sid
=
"26125010"
;
/*
private String sid = "26125010";
private String did = "26045002";
private String sendHost = "232.18.185.21";
private int sendPort = 8888;
private String recvGroup = "232.18.185.11";
private
int
recvPort
=
8888
;
private int recvPort = 8888;
*/
/** 网络接口名称,留空则
自动选择第一个支持组播的接口 ens192
*/
private
String
networkInterface
=
"
wlan1
"
;
/** 网络接口名称,留空则
按系统组播路由自动选择;也可手动指定。
*/
private
String
networkInterface
=
""
;
/** 状态查询间隔(秒),0=不自动查询 */
private
int
queryInterval
=
10
;
...
...
src/main/java/com/monitor/d2d/netty/NetworkInterfaceSelector.java
0 → 100644
View file @
141d1b58
package
com
.
monitor
.
d2d
.
netty
;
import
com.monitor.d2d.config.AppProperties
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Component
;
import
java.io.IOException
;
import
java.net.*
;
import
java.util.*
;
/** 收发共用一次选择结果,避免分别枚举时选到不同接口。 */
@Slf4j
@Component
public
class
NetworkInterfaceSelector
{
@Autowired
private
AppProperties
props
;
private
NetworkInterface
selected
;
public
synchronized
NetworkInterface
resolve
()
throws
IOException
{
if
(
selected
!=
null
)
return
selected
;
String
name
=
props
.
getNetworkInterface
();
if
(
name
!=
null
&&
!
name
.
trim
().
isEmpty
())
{
NetworkInterface
configured
=
NetworkInterface
.
getByName
(
name
.
trim
());
if
(
usable
(
configured
))
return
remember
(
configured
,
"手动配置"
);
log
.
warn
(
"配置的网络接口 [{}] 不存在或不支持已启用的 IPv4 组播,尝试自动选择"
,
name
);
}
// UDP connect 只查询系统路由,不发送数据包。
try
(
DatagramSocket
socket
=
new
DatagramSocket
(
null
))
{
socket
.
bind
(
new
InetSocketAddress
(
"0.0.0.0"
,
0
));
socket
.
connect
(
InetAddress
.
getByName
(
props
.
getSendHost
()),
props
.
getSendPort
());
NetworkInterface
routed
=
NetworkInterface
.
getByInetAddress
(
socket
.
getLocalAddress
());
if
(
usable
(
routed
)
&&
!
routed
.
isPointToPoint
())
return
remember
(
routed
,
"系统目标路由"
);
}
catch
(
IOException
ex
)
{
log
.
warn
(
"无法按目标路由选择网卡,尝试枚举可用接口: {}"
,
ex
.
getMessage
());
}
List
<
NetworkInterface
>
candidates
=
new
ArrayList
<>();
Enumeration
<
NetworkInterface
>
interfaces
=
NetworkInterface
.
getNetworkInterfaces
();
while
(
interfaces
!=
null
&&
interfaces
.
hasMoreElements
())
{
NetworkInterface
ni
=
interfaces
.
nextElement
();
if
(
usable
(
ni
)
&&
!
ni
.
isPointToPoint
())
candidates
.
add
(
ni
);
}
candidates
.
sort
(
Comparator
.
comparing
(
NetworkInterface:
:
isVirtual
)
.
thenComparingInt
(
NetworkInterface:
:
getIndex
));
if
(
candidates
.
isEmpty
())
throw
new
SocketException
(
"未找到已启用且支持 IPv4 组播的非回环网卡"
);
if
(
candidates
.
size
()
>
1
)
log
.
warn
(
"存在多个可用网卡且无法确定目标路由,采用候选列表首项: {}"
,
candidates
);
return
remember
(
candidates
.
get
(
0
),
"可用接口回退"
);
}
private
boolean
usable
(
NetworkInterface
ni
)
throws
SocketException
{
if
(
ni
==
null
||
!
ni
.
isUp
()
||
ni
.
isLoopback
()
||
!
ni
.
supportsMulticast
())
return
false
;
return
Collections
.
list
(
ni
.
getInetAddresses
()).
stream
().
anyMatch
(
a
->
a
instanceof
Inet4Address
);
}
private
NetworkInterface
remember
(
NetworkInterface
ni
,
String
reason
)
{
selected
=
ni
;
log
.
info
(
"组播网络接口: {} ({}),地址: {},选择依据: {}"
,
ni
.
getName
(),
ni
.
getDisplayName
(),
Collections
.
list
(
ni
.
getInetAddresses
()),
reason
);
return
ni
;
}
}
src/main/java/com/monitor/d2d/netty/UdpReceiver.java
View file @
141d1b58
...
...
@@ -14,7 +14,6 @@ import org.springframework.stereotype.Component;
import
javax.annotation.PostConstruct
;
import
javax.annotation.PreDestroy
;
import
java.net.*
;
import
java.util.Enumeration
;
/**
* UDP 组播接收端
...
...
@@ -30,12 +29,15 @@ public class UdpReceiver {
@Autowired
private
ReportInboundHandler
reportHandler
;
@Autowired
private
NetworkInterfaceSelector
interfaceSelector
;
private
NioEventLoopGroup
group
;
private
Channel
channel
;
@PostConstruct
public
void
start
()
throws
Exception
{
NetworkInterface
ni
=
resolveNetworkInterfac
e
();
NetworkInterface
ni
=
interfaceSelector
.
resolv
e
();
InetAddress
groupAddr
=
InetAddress
.
getByName
(
props
.
getRecvGroup
());
group
=
new
NioEventLoopGroup
(
1
);
...
...
@@ -56,34 +58,6 @@ public class UdpReceiver {
props
.
getRecvGroup
(),
props
.
getRecvPort
(),
ni
.
getName
());
}
/**
* 自动或按配置选择网络接口
*/
private
NetworkInterface
resolveNetworkInterface
()
throws
SocketException
{
String
ifName
=
props
.
getNetworkInterface
();
if
(
ifName
!=
null
&&
!
ifName
.
isEmpty
())
{
NetworkInterface
ni
=
NetworkInterface
.
getByName
(
ifName
);
if
(
ni
!=
null
)
return
ni
;
log
.
warn
(
"配置的网络接口 [{}] 不存在,尝试自动选择"
,
ifName
);
}
// 自动选择:第一个支持组播且已启动的非回环接口
Enumeration
<
NetworkInterface
>
nis
=
NetworkInterface
.
getNetworkInterfaces
();
while
(
nis
.
hasMoreElements
())
{
NetworkInterface
ni
=
nis
.
nextElement
();
if
(
ni
.
isUp
()
&&
ni
.
supportsMulticast
()
&&
!
ni
.
isLoopback
())
{
log
.
info
(
"自动选择网络接口: {}"
,
ni
.
getName
());
return
ni
;
}
}
// 回退到回环(仅用于本地测试)
NetworkInterface
lo
=
NetworkInterface
.
getByName
(
"lo"
);
if
(
lo
!=
null
)
{
log
.
warn
(
"未找到可用组播接口,回退到回环接口(仅限本地测试)"
);
return
lo
;
}
throw
new
IllegalStateException
(
"无法找到可用的网络接口"
);
}
@PreDestroy
public
void
stop
()
{
if
(
channel
!=
null
)
channel
.
close
();
...
...
src/main/java/com/monitor/d2d/netty/UdpSender.java
View file @
141d1b58
...
...
@@ -15,7 +15,7 @@ import org.springframework.stereotype.Component;
import
javax.annotation.PostConstruct
;
import
javax.annotation.PreDestroy
;
import
java.net.InetSocketAddress
;
import
java.net.NetworkInterface
;
import
io.netty.channel.socket.InternetProtocolFamily
;
/**
* UDP 组播发送端
...
...
@@ -28,6 +28,9 @@ public class UdpSender {
@Autowired
private
AppProperties
props
;
@Autowired
private
NetworkInterfaceSelector
interfaceSelector
;
private
NioEventLoopGroup
group
;
private
Channel
channel
;
private
InetSocketAddress
targetAddress
;
...
...
@@ -35,11 +38,12 @@ public class UdpSender {
@PostConstruct
public
void
start
()
throws
Exception
{
targetAddress
=
new
InetSocketAddress
(
props
.
getSendHost
(),
props
.
getSendPort
());
java
.
net
.
NetworkInterface
ni
=
interfaceSelector
.
resolve
();
group
=
new
NioEventLoopGroup
(
1
);
Bootstrap
b
=
new
Bootstrap
();
b
.
group
(
group
)
.
channel
(
NioDatagramChannel
.
class
)
.
option
(
ChannelOption
.
IP_MULTICAST_IF
,
NetworkInterface
.
getByName
(
props
.
getNetworkInterface
())
)
.
channel
Factory
(()
->
new
NioDatagramChannel
(
InternetProtocolFamily
.
IPv4
)
)
.
option
(
ChannelOption
.
IP_MULTICAST_IF
,
ni
)
.
option
(
ChannelOption
.
SO_REUSEADDR
,
true
)
.
handler
(
new
SimpleChannelInboundHandler
<
Object
>()
{
@Override
...
...
src/main/java/com/monitor/d2d/service/ApiController.java
View file @
141d1b58
...
...
@@ -108,23 +108,23 @@ public class ApiController {
private
int
num
=
0
;
// ──定时器──────────────────────────────────────────────────────────
@Scheduled
(
cron
=
"1 */30
* * * *"
)
public
void
autoSend5422
()
{
String
localIP
=
"127.0.0.1"
;
String
remoteIP
=
"127.0.0.1"
;
int
concurrency
=
4
;
try
{
for
(
int
i
=
0
;
i
<
concurrency
;
i
++)
{
int
count
=
num
*
concurrency
+
i
;
ObjectMapper
mapper
=
new
ObjectMapper
();
String
json
=
"{\"taskControl\":2,\"primaryFlag\":15,\"planNo\":\""
+
String
.
format
(
"%09d"
,
count
)+
"\",\"terminalStation\":\"TEST44621\",\"relayTaskCode\":16671,\"relayAntenna\":15,\"spacecraft\":\"TEST01\",\"orbitNo\":\""
+
String
.
format
(
"%05d"
,
count
)+
"\",\"transferNo\":1,\"captureStartTime\":\"20260701154300\",\"mode\":1,\"terminalAppProtocol\":5,\"terminalTransProtocol\":144,\"linkId\":\"LINK0\",\"initialRecvFrames\":0,\"initialRecvBytes\":0,\"terminalLinks\":[{\"primaryFlag\":15,\"routePlane\":0,\"terminalIp\":\""
+
remoteIP
+
"\",\"terminalPort\":27586,\"dataTransIp\":\""
+
localIP
+
"\",\"dataTransPort\":1001"
+
i
+
"}],\"outerEndpoints\":[{\"centerId\":\"TESTZX\",\"appProtocol\":0,\"initialSendFrames\":0,\"initialSendBytes\":0,\"transportProtocol\":144,\"links\":[{\"dataTransIp\":\""
+
localIP
+
"\",\"dataTransPort\":444"
+
i
+
",\"outerIp\":\""
+
remoteIP
+
"\",\"outerPort\":24584}]}]}"
;
Map
<
String
,
Object
>
parm
=
mapper
.
readValue
(
json
,
Map
.
class
);
sendCommand
(
"5422"
,
parm
);
}
log
.
info
(
"执行次数: {}"
,
num
++);
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
// @Scheduled(cron = "1 */1
* * * *")
//
public void autoSend5422() {
//
String localIP = "127.0.0.1";
//
String remoteIP = "127.0.0.1";
// int concurrency = 1
;
//
try {
//
for (int i = 0; i < concurrency; i++) {
//
int count = num * concurrency + i;
//
ObjectMapper mapper = new ObjectMapper();
//
String json = "{\"taskControl\":2,\"primaryFlag\":15,\"planNo\":\""+String.format("%09d", count)+"\",\"terminalStation\":\"TEST44621\",\"relayTaskCode\":16671,\"relayAntenna\":15,\"spacecraft\":\"TEST01\",\"orbitNo\":\""+String.format("%05d", count)+"\",\"transferNo\":1,\"captureStartTime\":\"20260701154300\",\"mode\":1,\"terminalAppProtocol\":5,\"terminalTransProtocol\":144,\"linkId\":\"LINK0\",\"initialRecvFrames\":0,\"initialRecvBytes\":0,\"terminalLinks\":[{\"primaryFlag\":15,\"routePlane\":0,\"terminalIp\":\""+remoteIP+"\",\"terminalPort\":27586,\"dataTransIp\":\""+localIP+"\",\"dataTransPort\":1001"+i+"}],\"outerEndpoints\":[{\"centerId\":\"TESTZX\",\"appProtocol\":0,\"initialSendFrames\":0,\"initialSendBytes\":0,\"transportProtocol\":144,\"links\":[{\"dataTransIp\":\""+localIP+"\",\"dataTransPort\":444"+i+",\"outerIp\":\""+remoteIP+"\",\"outerPort\":24584}]}]}";
//
Map<String, Object> parm = mapper.readValue(json, Map.class);
//
sendCommand("5422",parm);
//
}
//
log.info("执行次数: {}", num++);
//
} catch (IOException e) {
//
e.printStackTrace();
//
}
//
//
}
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment