C# TCPclient 服务器保持长连接的一种办法(变相的心跳包功能)

2023-10-26

        本文章向大家介绍C# TCPclient 服务器保持长连接的一种办法(变相的心跳包功能),主要包括C# TCPclient 服务器保持长连接的一种办法(变相的心跳包功能)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;


namespace ALARMIP
{
    public partial class Form1 : Form
    {      
       //客户端定时向服务器发送查询指令
//服务器内置时钟计数,收到查询指令清零,计数超过则跳出循环,重新产生线程,线程内运行阻塞等待新的连接
//这样如果客户端连接一次就可以持续查询服务器设备,如果出现网络异常或者链接中断,只需客户端重新建立连接
//这个实例的好处是避免采用异步方法造成的非阻塞连接(要求客户端也用非阻塞方式,很多第三方工具无法调试)
       
        byte[] pollingCommand = new byte[12] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x30 };
        // 客户端轮询指令,事务处理标识2字节,协议标识2字节,长度标识2字节,单元标识00,功能标识0A,起始处理器号,总处理器数
        //00 00 00 00 00 06 01 04 00 01 00 30 
 
        byte[] infoTCP = new byte[57] {0x00, 0x00, 0x00, 0x00, 0x00, 0x33,0x61, 0x04, 0x30,           
                                                                               
                                    0x00,0x00,0x00,                  //0
                                    0x00,0x00,0x00 ,                     //pm1
                                    0x00,0x00,0x00,                     //2
                                    0x00,0x00,0x00,                     //3
                                    0x00,0x00,0x00,                        //4
                                    0x00,0x00,0x00,                     //5
                                    0x00,0x00,0x00,                    //6
                                    0x00,0x00,0x00,                     //7
                                    0x00,0x00,0x00,                    //8
                                    0x00,0x00,0x00,                     //9
                                    0x00,0x00,0x00,                    //10
                                    0x00,0x00,0x00,                   //11
                                    0x00,0x00,0x00,                //12
                                    0x00,0x00,0x00,                //13
                                    0x00,0x00,0x00,               //14
                                    0x00,0x00,0x00                 //15
        };

        bool isAlarmIPReady = true  ;                       //服务器数据汇总是否完成,由时钟确定,默认500ms,接收到轮询指令且该值为1时答复,否则不做应答;应答后修改为0
        bool isPolling=true ;     //是否收到轮询指令
        private bool isListening; //控制连接传输循环
        private TcpListener listener;
        private Thread aThread;
        private bool isTcpConnected; //存在连接线程的标志,控制线程
        private int pollingLost;   //无客户端查询次数,网络断开也可用,定时器自动加1,通讯成功则清零
  

     
        public Form1()
        {
            InitializeComponent();
        }


        private void Form1_Load(object sender, EventArgs e)
        { 
            timer1.Start();
            Thread.Sleep(500);
            listener = new TcpListener(IPAddress.Any, 502);   //新建socket,允许局域网所有终端访问
            listener.Start();
            aThread = new Thread(Queue1Thread);   //连接线程
            isTcpConnected = true;  //连接状态标志
            
            aThread.Start();
        }
 
            
        private void timer1_Tick(object sender, EventArgs e)
        {
            isAlarmIPReady = true;  //每500ms标志一次
         
            if(!isListening)
            {
                if (!isTcpConnected)
                {
                    aThread = new Thread(Queue1Thread);
                    isTcpConnected = true; //立即标识启动连接,避免开多个线程
                    
                    aThread.Start();
                }
            }
            else
            {
                if(++pollingLost>10)
                {
                    pollingLost = 10;// 简易的心跳包,根据
                    isListening = false; //让TCP线程跳出循环
                }
            }
        }


        private void Queue1Thread(object state)
        {
            TcpClient client = new TcpClient();
            client = listener.AcceptTcpClient();  //阻塞,等待新的连接
            isListening = true; //该值应该在子线程赋值,如果在主线程,有可能是上一个线程的值false,直接跳出下面的循环而断开连接
            pollingLost = 0; //同上
            while (isListening)
            {
                if (client != null)
                {
                    NetworkStream stream = client.GetStream();  //这个对象有系统回收
                    byte[] buffer = new byte[256];
                    int ki = client.ReceiveBufferSize;
                    this.Invoke((EventHandler)(delegate
                    {
                        //this.Text = ki.ToString()+DateTime.Now .ToLongTimeString();
                    }));

                    stream.Read(buffer, 0, 256);
                    if (ki > 11)
                    {
                        isPolling = true;
                        for (int i = 2; i < 11; i++)
                        {
                            if (pollingCommand[i] != buffer[i])
                            {
                                isPolling = false; //对客户端请求验证,避免错码
                            }
                        }
                        if (isAlarmIPReady & isPolling)
                        {
                            isAlarmIPReady = false;
                            pollingLost = 0;  //连接失败数清零
                            infoTCP[0] = buffer[0];
                            infoTCP[1] = buffer[1];
                            stream.Write(infoTCP, 0, 57);
                            // MessageBox.Show(infoTCP [5].ToString());
                        }
                       
                    }
                }
            }
            client.Close();  //加此处理,则5秒超时后,客户端不重连而发送查询后连接将关闭;如果不做处理,系统将自动回收,客户端不重连发送查询后连接显示保持但是实际上已经断开了连接
            isTcpConnected = false; 
        }  
    }
}

http://www.manongjc.com/article/37725.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# TCPclient 服务器保持长连接的一种办法(变相的心跳包功能) 的相关文章

  • 基于Centos7+pycharm搭建python获取爬虫小项目

    一 安装python环境 网上教程查阅 安装成功后运行 python 查看版本 python V 二 安装pycharm 应在步骤一完成后进行 到pycharm官网下载最新版本 下载链接 https www jetbrains com py
  • 详解 Springboot 中使用 Aop

    一 什么是 Aop AOP Aspect Oriented Programming 意为面向切面编程 可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术 AOP的编程思想是把对类对象的横切问题点 从
  • CentOS 修改时间

    Centos系统时间分为系统时间和硬件时间 二者必须都修改 重启系统才会永久生效 查询时间常用命令 date date R date z hwclock r 一 修改时区 修改时区 ln sf usr share zoneinfo Asia
  • XMind思维导图的结构逻辑该如何体现?3个功能完美体现!

    假设你在玩 模拟城市 但你必须使用以下工具来构建城市 中心主题 城市中心 关键思想 主要道路 次要的思想 次要的道路 标志 地标图片 那么你要怎么安排才能让城市结构附有逻辑性 让城市的规划更加合理 这就是我们将要讨论的问题 同样在我们的思维
  • 初始化列表的特性和构造函数的工作原理

    对于构造函数我们一直有个误区 就是构造函数用于初始化成员变量创建对象 实际上并不是这样的 真正的初始化并不是在构造函数中完成的 而是在初始化列表中完成的 构造函数中的实际上是赋值操作 要了解构造函数的工作原理 得先了解什么是初始化列表 初始
  • 快速达成目标的12种方

    2006 05 04 16 20 15 快速达成目标的12种方法 告诉自己你能主宰命运只有确立了前进的目标 一个人才会最大可能地发挥自己的潜力 主宰自己的命运 在你身上拥有钻石宝藏 美国宾夕法尼亚州著名学府坦普尔大学创始人康惠尔 在演讲中

随机推荐

  • 在superset中快速制作报表或仪表盘

    在中小型企业 当下需要快速迭代 快速了解运营效果的业务 急需一款开源 好用 能快速迭代生产的报表系统 老板很关心 BI工程师很关心 同时系统开发人员也同样关心 一个好的技术选型往往能够帮助公司减少很多成本 并且也不用BI或软件开发同事为了快
  • FRP运行过程中发现的安全漏洞,没有办法修复

    最近经常发送frp搭建外网访问内网不稳定 经过多次排查发现一个可怕的漏洞 这些 goroutines 结束之前正在等待一个 channel 关闭 而这个 channel 永远不会关闭 一个常见的死锁问题 这个进程毫无任何理由吃掉了 90 的
  • Hive Order By、Sort By、Distrbute By、Cluster By区别

    1 Order By 全局排序 只有一个Reducer 2 Sort By 分区内有序 3 Distrbute By 类似MR中Partition 进行分区 结合sort by使用 4 Cluster By 当Distribute by和S
  • XXX packages are looking for funding run `npm fund` for details解决方法

    今天用VScode导入一个vue项目 实现npm install 安装依赖遇到了一些小问题 搞了好久才终于搞好了 下面来直接进入主题 当在终端执行npm install时出现这种情况 然后我们再执行npm update 接下来我们执行npm
  • Mybatis框架(复杂动态SQL),一对一,一对多,多对多

    复合条件查询 动态SQL MyBatis 的强大特性之一便是它的动态 SQL 如果你有使用 JDBC 或其它类似框架的经验 你就能体会到根据不同条件拼接 SQL 语句的痛苦 例如拼接时要确保不能忘记添加必要的空格 还要注意去掉列表最后一个列
  • 哈工大OS实验五---基于内核栈切换的进程切换

    基于内核栈切换的进程切换 实验目的 将linux 0 11中采用的TSS切换部分去掉 取而代之的是基于堆栈的切换程序 写成一段基于堆栈切换的代码 要实现基于内核栈的任务切换 主要完成如下三件工作 重写switch to 将重写的switch
  • Mysql高级部分系列(四)

    1 数据库的设计规范 1 1 为什么不使用自增ID 1 1 1 自增ID的问题 自增ID做主键 简单易懂 几乎所有数据库都支持自增类型 只是实现上各自有所不同而已 自增ID除了简单 其他都是缺点 总体来看存在以下几方面的问题 1 1 1 1
  • idea 部署git总结

    idea 部署git总结 github密匙快捷获取方法 idea将本地项目上传到远程仓库GitHub 报错 error src refspec master does not match any Everything up to date
  • 【线程池上篇】4种常用线程池介绍

    一 线程池介绍 概念 使用原因 线程池就是提前创建好一些线程放在一起的集合 线程池的工作模式时拿到任务后在自己的池子里找看谁闲着 这个活就让谁去干 多线程模式下 系统需要不断地启动和关闭新线程 这个过程不但消耗资源而在存在线程间过渡的不安全
  • C 程序结构

    原文链接 https www runoob com cprogramming c program structure html 在我们学习 C 语言的基本构建块之前 让我们先来看看一个最小的 C 程序结构 在接下来的章节中可以以此作为参考
  • 通过python技术获取甲流分布数据

    近期 多地学校出现因甲流导致的班级停课 儿科甲流患者就诊量呈数倍增长 此轮甲流为何如此严重 感染甲流之后会出现哪些症状 经过专家的介绍甲流之所以这么严重有这些原因导致的 一 疫情完全放开后很多孩子不戴口罩了 预防流感的作用会下降 二是 免疫
  • background-position的向右对齐用法

    一直只知道background position x轴位置 y轴位置 如果靠近左边偏移7px就写成background position 7px 20px 这样的 但是像右要怎么办 以前我是傻傻的给父容器计算了宽度 然后就向左偏移固定的宽度
  • 为什么推荐科研工作使用git

    为什么推荐科研工作使用git 每个人都会犯错 而使用Git 的最大好处就在于 几乎在所有的情况下你都能 撤消 你的错误操作 比如如果你忘记了把一个小小的改动包含进来 因此你要改正你的上个提交 又或者你想要撤销一个完整的提交 因为这个功能有可
  • 【C/C++】获取计算机CPUID序列号

    1 GetGPUId h文件 pragma once include
  • 【解决报错】c#使用ManagedWifi报错出现“不能作为非托管结构进行封送处理;无法计算有意义的大小或偏移量。”

    最近在做C 上位机wifi通信的时候使用了MangedWifi库 但这个库并没有想象中好用 遇到了不少问题 首先网上流传的例程又不能运行 再接着当wifi断开或连接时会异常退出的bug 通过反反复复的调试后 我最终确认了错误的来源 发现是M
  • 微信公众号 config:fail,Error: 系统错误,错误码:1

    微信公众号开发 微信开发者工具 打开调试模式 出现config fail Error 系统错误 错误码 1 查看一下wx config是否成功渲染了 重新赋值 修改后的代码如下 chooseImage var this this 新增代码块
  • 生产环境lvm磁盘扩容!!!

    一次就好 亲身体验生产环境lvm磁盘扩容 这一天体验了真正的生产环境 三急 中午客户打电话说报表几个小时没更新了 是不是你们系统有问题啊 于是开始排除发现磁盘空间满了 需要进行扩容 咱又没有扩容经验潜心研究一下午 终于得出结论 以下将描述我
  • 如何将计算机的硬盘分割,电脑硬盘如何快速分区

    电脑硬盘一般有2个盘或者4个盘 怎样自己增添一个硬盘 或者来均分电脑那300G或者500G的硬盘空间呢 今天学习啦小编给大家介绍下电脑硬盘如何快速分区吧 电脑硬盘快速分区方法一 1 点击我的电脑 点击鼠标右键 选择管理项 2 打开后选择磁盘
  • Python基础教程,Python入门教程(非常详细)

    Python 英文本意为 蟒蛇 直到 1989 年荷兰人 Guido van Rossum 简称 Guido 发明了一种面向对象的解释型编程语言 后续会介绍 并将其命名为 Python 才赋予了它表示一门编程语言的含义 图 1 Python
  • C# TCPclient 服务器保持长连接的一种办法(变相的心跳包功能)

    本文章向大家介绍C TCPclient 服务器保持长连接的一种办法 变相的心跳包功能 主要包括C TCPclient 服务器保持长连接的一种办法 变相的心跳包功能 使用实例 应用技巧 基本知识点总结和需要注意事项 具有一定的参考价值 需要的