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

C#代码Ping IP结果与命令行不一致,原因何在?

C# Ping代码与命令行Ping结果不一致的原因分析

问题描述

我编写了一段用于Ping IP并记录日志的C#代码:

private async ValueTask PingMachine() {
        var timesToPing = 4;
        var counter = 1;

        while (counter <= timesToPing) {
            var reply = await Pinger();
            foreach (var r in reply) {
               TagService.log_PLC.AppendLine($" Pinged {TagService.IP_PLC_List} {counter} times time:{r.RoundtripTime} status: {r.Status.ToString()}");
            }
        }
        counter++;
}

private async Task<IEnumerable<PingReply>> Pinger() {
    List<string> addresses = new List<string>();
    if (Check_IP_Correct(TagService.IP_PLC_List) == true) {
        addresses.Add(TagService.IP_PLC_List);
    }

    var tasks = addresses.Select(async ip => await new Ping().SendPingAsync(ip, 1000));
    var reply = await Task.WhenAll(tasks);
    return reply;
}

测试在线IP时无异常,但测试某不可达IP时,日志显示:

Pinged 10.92.XXX.XX 1 times time:0 status: TimedOut
Pinged 10.92.XXX.XX 2 times time:0 status: TimedOut
Pinged 10.92.XXX.XX 3 times time:0 status: TimedOut
Pinged 10.92.XXX.XX 4 times time:0 status: DestinationHostUnreachable

而在同一服务器使用命令行ping该IP时,每次均返回:

Reply from 100.72.XXX.XX: Destination host unreachable.
Reply from 100.72.XXX.XX: Destination host unreachable.
Reply from 100.72.XXX.XX: Destination host unreachable.
Reply from 100.72.XXX.XX: Destination host unreachable.

我认为命令行的结果是正确的,请问为何C#代码返回的结果不同?可能存在什么问题?

原因分析

1. 超时时间设置不匹配

Windows命令行ping默认超时时间是4秒,而你的C#代码里设置的超时仅为1000毫秒(1秒)。当目标IP不可达时,路由设备返回的ICMP“目标不可达”包可能因网络延迟,没能在1秒内到达程序,导致前几次请求被判定为超时;后续请求时网络栈缓存了路由信息,错误包能更快返回,才会显示DestinationHostUnreachable。

2. ICMP响应处理逻辑差异

命令行ping会直接解析所有ICMP响应包,包括路由返回的错误包;而C#的Ping类底层实现和系统命令行的ICMP调用逻辑有区别,对错误包的优先级处理不同。前几次请求时,Ping类可能优先触发超时逻辑,直到网络栈明确返回不可达的错误状态,才会更新返回值。

3. 代码存在逻辑错误

你的PingMachine方法里,counter++写在了while循环的外面,这会导致循环条件counter <= timesToPing永远成立(counter始终为1),理论上会无限循环。但你的日志显示执行了4次,大概率是代码缩进错误,counter++应该放在循环内部。这个错误会导致重复发送Ping请求,而网络栈的路由状态逐渐更新后,才返回正确的不可达状态。

4. 网络栈缓存机制影响

第一次发送Ping请求后,系统网络栈需要时间缓存“目标不可达”的路由信息。前几次请求时缓存未生效,程序收到超时;后续请求时缓存生效,直接返回正确的错误状态。而命令行ping可能会利用已有的系统路由缓存,所以每次都能正确捕获到不可达的响应。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 12:37:03