You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Tomcat中使用Java MulticastSocket切换网络模式时出现jmdns日志异常求助

问题:Tomcat部署IP切换代码后出现JmDNS异常日志

我有一段用来切换设备网络IP模式(静态/DHCP)的Java代码,在独立类中运行完全正常,但部署到Tomcat的Web应用后,每次执行都会打印一堆JmDNS相关的警告和错误日志,想请大家帮忙分析原因和解决办法。

执行的代码

MulticastSocket multicastSocket = new MulticastSocket(5353);
InetAddress address = InetAddress.getByName("224.0.0.251");
multicastSocket.joinGroup(address);
multicastSocket.setLoopbackMode(true);
StringBuilder command = new StringBuilder();
command.append("SET_");
command.append(macaddress);
command.append("_<IPNetworkSettings><IPAddress>");
command.append("0.0.0.0");
command.append("</IPAddress><SubnetMask>");
command.append("x.x.x.x");
command.append("</SubnetMask><Gateway>");
command.append("x.x.x.x");
command.append("</Gateway></IPNetworkSettings>");
byte[] message = command.toString().getBytes();
DatagramPacket packet = new DatagramPacket(message, message.length, address, MULTICAST_PORT);
multicastSocket.send(packet);
byte[] buf = new byte[1000];
multicastSocket.setSoTimeout(30000);
DatagramPacket recv = new DatagramPacket(buf, buf.length);
multicastSocket.receive(recv);
String recmessage = new String(recv.getData(), US_ASCII).trim();
multicastSocket.leaveGroup(address);

出现的异常日志

Dec 19, 2017 7:46:50 PM javax.jmdns.impl.constants.DNSRecordClass classForIndex WARNING: Could not find record class for index: -1
Dec 19, 2017 7:46:50 PM javax.jmdns.impl.DNSIncoming$MessageInputStream readName SEVERE: bad domain name: possible circular name detected. Bad offset: 0xffffffff at 0x91
Dec 19, 2017 7:46:50 PM javax.jmdns.impl.constants.DNSRecordType typeForIndex SEVERE: Could not find record type for index: -1
Dec 19, 2017 7:46:50 PM javax.jmdns.impl.DNSIncoming readQuestion SEVERE: Could not find record type: dns[query,199.xxx.xxx.xxx:5353, length=147, id=0x0, flags=0x545f:aa, questions=935 questions: [DNSQuestion@19280069 type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: 199.xxx.xxx.xxx255.255.255.0199.xxx.xxx.xxx??????.] [DNSQuestion@5804116 type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ] [DNSQuestion@15634375 type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ] [DNSQuestion@17093854 type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ] [DNSQuestion@23358883 type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ] [DNSQuestion@30187115 type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ] [DNSQuestion@25734882 type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ] [DNSQuestion@75113 type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ] [DNSQuestion@15094207 type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ]

原因分析

这堆日志其实是JmDNS(Java Multicast DNS)组件抛出的解析错误,问题根源在于:

  • 你的代码使用了5353端口,这是mDNS(多播DNS)的默认端口,而Tomcat环境中很可能已经有其他应用或组件在使用JmDNS监听这个端口做服务发现。
  • 当你的代码发送自定义格式的多播数据包到5353端口时,JmDNS会尝试把这些数据包当作标准的mDNS协议包来解析,但你的数据包是自定义的XML命令格式,完全不符合mDNS规范,所以JmDNS解析失败,就打印了这些错误日志。

解决方案

最直接有效的办法是更换多播端口,避开mDNS的默认5353端口,具体步骤如下:

  1. 修改代码中的端口配置:

    • new MulticastSocket(5353)替换为其他未被占用的端口,比如5354
    • 同时确保MULTICAST_PORT常量的值也改成对应的新端口(比如5354)
    • 还要确认你的目标设备也配置为监听这个新的多播端口,能接收并解析你的命令
  2. 修改后的代码片段示例:

// 更换为非5353的端口
int CUSTOM_MULTICAST_PORT = 5354;
MulticastSocket multicastSocket = new MulticastSocket(CUSTOM_MULTICAST_PORT);
InetAddress address = InetAddress.getByName("224.0.0.251");
multicastSocket.joinGroup(address);
multicastSocket.setLoopbackMode(true);
// ... 其他代码不变 ...
DatagramPacket packet = new DatagramPacket(message, message.length, address, CUSTOM_MULTICAST_PORT);
// ... 其他代码不变 ...

如果因为设备限制必须使用5353端口,那可以尝试在代码中明确指定绑定的网卡,避免和JmDNS的监听冲突,但这种方式兼容性较差,不如换端口来得稳妥。

内容的提问来源于stack exchange,提问作者Srikanth

火山引擎 最新活动