You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java程序无法接收C程序发送的UDP数据问题排查

解决Java UDP无法接收指定端口数据的方案

针对你的场景,C程序能正常接收但Java程序不行,可从以下几个方向排查并修复:

  • 明确绑定目标IP地址
    Java的DatagramSocket如果只指定端口,默认会绑定到0.0.0.0(所有可用接口),但在多网卡环境下可能出现路由匹配问题。直接绑定到目标IP192.168.23.98,和C程序的绑定逻辑对齐:
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

public class UdpReceiver {
    public static void main(String[] args) throws SocketException {
        try {
            InetAddress localIp = InetAddress.getByName("192.168.23.98");
            // 绑定到指定IP和端口
            DatagramSocket socket = new DatagramSocket(27011, localIp);
            System.out.println("绑定到 " + localIp + ":27011 成功");
            // 后续接收逻辑
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  • 开启端口重用选项
    C程序通常默认开启SO_REUSEADDR,Java需要手动设置该选项,避免系统层面的端口占用限制:
// 在创建socket后添加
socket.setReuseAddress(true);
// 对于Java 7+,可尝试开启SO_REUSEPORT(部分系统如Linux支持,Windows可能不兼容)
try {
    socket.setOption(StandardSocketOptions.SO_REUSEPORT, true);
} catch (Exception e) {
    // 不支持则忽略,不影响核心功能
}
  • 匹配数据接收逻辑
    确保接收缓冲区大小和数据读取方式与发送端一致,避免因缓冲区或解析问题导致数据丢失:
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import javax.xml.bind.DatatypeConverter;

public class UdpReceiver {
    public static void main(String[] args) throws Exception {
        InetAddress localIp = InetAddress.getByName("192.168.23.98");
        DatagramSocket socket = new DatagramSocket(27011, localIp);
        socket.setReuseAddress(true);

        byte[] buffer = new byte[3]; // 对应发送端3字节的包长度
        DatagramPacket packet = new DatagramPacket(buffer, buffer.length);

        while (true) {
            socket.receive(packet);
            // 转换为十六进制字符串验证,匹配Wireshark的02153f
            String receivedHex = DatatypeConverter.printHexBinary(packet.getData()).substring(0, 6);
            System.out.println("收到数据: " + receivedHex);
            // 重置packet长度,避免下次读取受上次数据影响
            packet.setLength(buffer.length);
        }
    }
}

注意每次接收后要重置DatagramPacket的长度,否则后续接收会沿用之前的长度值,导致数据读取异常。

  • 绑定到指定物理网络接口
    如果多网卡环境下IP绑定仍无效,可直接绑定到目标网卡ethernet_32773:
import java.net.*;
import java.util.Enumeration;

public class UdpReceiver {
    public static void main(String[] args) throws Exception {
        NetworkInterface targetNic = null;
        Enumeration<NetworkInterface> nicList = NetworkInterface.getNetworkInterfaces();
        
        // 遍历找到目标网卡
        while (nicList.hasMoreElements()) {
            NetworkInterface nic = nicList.nextElement();
            if (nic.getName().equals("ethernet_32773")) {
                targetNic = nic;
                break;
            }
        }

        if (targetNic == null) {
            System.err.println("未找到目标网卡");
            return;
        }

        // 获取网卡对应的192.168.23.98地址
        InetAddress localIp = null;
        for (InterfaceAddress addr : targetNic.getInterfaceAddresses()) {
            InetAddress ip = addr.getAddress();
            if (ip instanceof Inet4Address && ip.getHostAddress().equals("192.168.23.98")) {
                localIp = ip;
                break;
            }
        }

        DatagramSocket socket = new DatagramSocket(new InetSocketAddress(localIp, 27011));
        socket.setReuseAddress(true);
        // 后续接收逻辑
    }
}
  • 排查系统防火墙权限
    即使C程序能接收,Java程序可能被系统防火墙拦截(如Windows Defender、Linux iptables)。可临时关闭防火墙测试,或给Java程序添加UDP端口27011的接收权限。

内容的提问来源于stack exchange,提问作者S.kh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 10:56:19