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

为什么我的C# .NET Core 3.1代码Windows运行正常却在Linux抛异常

问题根因定位

首先可以明确:你看到的for (int i = 0; i < PING_PACKET_SIZE; i++)行抛出空引用是调试行号偏移导致的误报:这行代码所有变量都是值类型/常量,pingPkt是刚实例化的List,不存在空对象,不可能触发空引用异常。
出现行号偏移的原因是Linux下发布的Release版本默认裁剪了调试符号(PDB文件),运行时抛出异常时匹配的行号是不准确的,实际异常出现在后续代码中。

实际触发空引用的常见场景(仅Linux平台出现的原因)

.NET Core 3.1 跨平台实现中,Linux和Windows的Ping类逻辑差异很大:
Windows下Ping类直接调用系统ICMP原生API,稳定性高;而.NET Core 3.1 版本的Linux下Ping类是通过调用系统ping命令实现的,存在多个已知的跨平台兼容性bug,最容易触发空引用的两种情况:

  1. 调用pingSender.Send()返回了null的PingReply对象,后续访问reply.Status时触发空引用,这个bug仅存在于.NET Core 3.x的Linux实现中,Windows版本不会返回null
  2. 运行程序的Linux用户没有ICMP调用权限,或者系统禁用了普通用户的ping权限,Ping类内部实现抛出未正确处理的空引用
修复方案
  • 第一步:修正代码空值判断

在访问PingReply前先做空检查,同时增加入参合法性校验:

public static double ping(string ipAddress, Int64 timeoutMs)
{
    // 先加参数校验
    if (string.IsNullOrWhiteSpace(ipAddress))
    {
        throw new ArgumentNullException(nameof(ipAddress));
    }
    const Int32 PING_PACKET_SIZE = 64;
    const Int32 DEFAULT_TIMEOUT_MS = 200;
    try
    {
        Ping pingSender = new Ping();
        PingOptions options = new PingOptions();
        options.DontFragment = true;

        var pingPkt = new List<byte>();

        for (int i = 0; i < PING_PACKET_SIZE; i++)
        {
            var val = Convert.ToByte(i + '0');
            pingPkt.Add(val);
        }

        int timeout = (Int32)(timeoutMs == 0 ? DEFAULT_TIMEOUT_MS : timeoutMs);

        PingReply reply = pingSender.Send(ipAddress, timeout, pingPkt.ToArray(), options);
        // 新增reply空值判断
        if (reply == null)
        {
            Console.WriteLine("Ping reply is null (Linux platform compatibility issue)");
            return -1;
        }
        if (reply.Status == IPStatus.Success)
        {
            return reply.RoundtripTime;
        }
        else
        {
            throw new Exception($"Ping Reply was not received! Reply Status: {reply.Status}");
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
        return -1;
    }
}
  • 第二步:Linux环境校验

    1. 先用目标Linux用户在终端手动执行ping 目标IP -c 1,确认ping权限正常、目标地址可连通
    2. 如果权限不足,可以给程序增加cap_net_raw权限(无需root运行):sudo setcap cap_net_raw=ep 你的程序路径,或者临时用sudo运行测试
  • 第三步:版本升级(建议)

.NET Core 3.1早已停止官方支持,升级到.NET 6或更高版本后,微软已经修复了Linux下Ping类的绝大多数兼容性bug,也可以从根本上避免这个问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 11:30:05