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端口,具体步骤如下:
修改代码中的端口配置:
- 将
new MulticastSocket(5353)替换为其他未被占用的端口,比如5354 - 同时确保
MULTICAST_PORT常量的值也改成对应的新端口(比如5354) - 还要确认你的目标设备也配置为监听这个新的多播端口,能接收并解析你的命令
- 将
修改后的代码片段示例:
// 更换为非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




