导读:本期聚焦于小伙伴创作的《C#怎么判断网络是否掉线?C#如何实现心跳包检测机制?》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C#怎么判断网络是否掉线?C#如何实现心跳包检测机制?》有用,将其分享出去将是对创作者最好的鼓励。

在C#网络编程里,判断网络是否掉线不能只依赖Socket的Connected属性,因为该属性只反映上次操作的态,无法感知网线被拔或远端静默崩溃。更可靠的做法是引入心跳包检测机制,即双方定期互发少量探测数据,依据是否收到回应来判定链路健康。

C#怎么判断网络是否掉线?C#如何实现心跳包检测机制?

为什么需要心跳包

TCP协议本身有保活机制,但默认超时时间往往长达两小时,无法满足实时业务需求。通过应用层心跳包,我们可以自定义间隔与超时阈值,快速发现掉线并触发重连或资源清理。

基于TcpClient的简单实现

下面示例展示一个客户端定时发送心跳并在指定时间内未收到回应时判定掉线的核心逻辑。

using System;
using System.Net.Sockets;
using System.Threading;
using System.Text;

class HeartbeatClient
{
    private TcpClient client;
    private NetworkStream stream;
    private Timer heartbeatTimer;
    private DateTime lastReceiveTime;
    private readonly object lockObj = new object();

    public void Start(string ip, int port)
    {
        client = new TcpClient();
        client.Connect(ip, port);
        stream = client.GetStream();
        lastReceiveTime = DateTime.Now;

        // 启动接收线程
        Thread recvThread = new Thread(ReceiveLoop);
        recvThread.IsBackground = true;
        recvThread.Start();

        // 每3秒发送一次心跳
        heartbeatTimer = new Timer(SendHeartbeat, null, 0, 3000);
    }

    private void SendHeartbeat(object state)
    {
        try
        {
            byte[] data = Encoding.ASCII.GetBytes("PING");
            stream.Write(data, 0, data.Length);
        }
        catch
        {
            Console.WriteLine("发送心跳失败,连接可能已断开");
        }

        // 检查超时:超过6秒未收到任何数据视为掉线
        lock (lockObj)
        {
            if ((DateTime.Now - lastReceiveTime).TotalSeconds > 6)
            {
                Console.WriteLine("心跳超时,网络已掉线");
                // 此处可执行重连逻辑
            }
        }
    }

    private void ReceiveLoop()
    {
        byte[] buffer = new byte[1024];
        try
        {
            while (true)
            {
                int len = stream.Read(buffer, 0, buffer.Length);
                if (len == 0) break;
                lock (lockObj)
                {
                    lastReceiveTime = DateTime.Now;
                }
                string msg = Encoding.ASCII.GetString(buffer, 0, len);
                if (msg == "PONG")
                {
                    Console.WriteLine("收到服务端心跳回应");
                }
            }
        }
        catch
        {
            Console.WriteLine("接收线程异常,连接断开");
        }
    }
}

关键注意事项

  • 心跳间隔与超时时间应根据业务容忍度设定,一般超时为间隔的2到3倍。
  • 多线程访问lastReceiveTime等共享字段时必须加锁,避免竞态。
  • 掉线后应及时关闭Socket并释放NetworkStream,防止句柄泄露。
  • 若使用异步async/await,可用CancellationToken控制心跳任务的启停。

服务端如何配合

服务端在收到PING后应回写PONG,同时也可主动向客户端发心跳以检测死连接。若连续多次未收到某客户端心跳,则可从在线列表中移除并关闭对应Socket。

心跳包内容应尽量小,避免占用带宽,通常使用固定字符串或单字节即可。

使用Ping类做辅助检测

有时可在应用层心跳之外,用System.Net.NetworkInformation.Ping对网关做ICMP探测,但要注意部分环境禁用了ICMP,因此不能单独依赖它判断程序连接状态。

using System.Net.NetworkInformation;

public bool GatewayReachable(string host)
{
    Ping ping = new Ping();
    try
    {
        PingReply reply = ping.Send(host, 1000);
        return reply.Status == IPStatus.Success;
    }
    catch
    {
        return false;
    }
}

总结

C#判断网络掉线的核心在于主动探测而非被动等待。心跳包机制以低成本方式补足了TCP感知延迟的缺陷,配合合理的超时与线程管理,可显著提升网络通信的稳健性。

C#网络掉线检测心跳包修改时间:2026-07-28 05:30:27

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。