C#/WinFrom TCP通信+ 网线插拔检测+客服端异常掉线检测

Winfor Tcp通信(服务端)

今天给大家讲一下C# 关于Tcp 通信部分,这一块的教程网上一大堆,不过关于掉网,异常断开连接的这部分到是到是没有多少说明,有方法 不过基本上最多的两种方式(1.设置一个超时时间,2.单独整个心跳上报

我觉得那个不好用,所以就给大家分享一下 第三种方式! 就比如 作为 服务端 能够快速的检测到客户端 掉线,然后做处理。

然后说一下 这个篇文章 只讲 服务端的内容,如果想看完整通信 的建议去看看其他的帖子


1.首先是IP地址 :

作为服务端 首先就是需要自己的IP地址,通过下面函数获取到当前主机多个 ID地址,返回一个列表

csharp 复制代码
        /// <summary>
        /// 获取本地的IP地址
        /// </summary>
        /// <returns></returns>
        private List<String> GetLocalIPAddress()
        {
            List<String> AddressIP = new List<string>();
            foreach (IPAddress _IPAddress in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
            {
                if (_IPAddress.AddressFamily.ToString() == "InterNetwork")
                {
                    AddressIP.Add(_IPAddress.ToString());
                }
            }
            return AddressIP;
        }

2.其次就是开启TCP服务

csharp 复制代码
        static bool IsTcpStart_ZX = false;            //判断TCP是否是否开启  开启状态下有效 
        IPEndPoint TcpIpep_ZX = null;                 //连接TCP终端地址
         Socket socketSever_ZX = null;
        /// <summary>
        /// 创建TCP
        /// </summary>
        /// <param name="ipAddrs"></param>        
        /// <param name="port"></param>
        /// <returns></returns>
        private bool creatTcpSever_ZX(string ipAddrs, string port)
        {
            try
            {
                TcpIpep_ZX = new IPEndPoint(IPAddress.Parse(ipAddrs), int.Parse(port)); // 本机IP和监听端口号                
                socketSever_ZX = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                socketSever_ZX.Bind(TcpIpep_ZX);
                socketSever_ZX.Listen(1);
                socketSever_ZX.IOControl(IOControlCode.KeepAliveValues, KeepAlive(1, 1000, 1000), null);  //保活时间 用于判断客户端 非正常断开(程序引起的掉线)
                IsTcpStart_ZX = true;
               /* this.Invoke(new Action(() =>
                {
                    toolStripLabel1.Text = "TCP 服务开启成功!";
                }));*/
                threadSever_ZX = new Thread(Listenning_ZX);
                threadSever_ZX.IsBackground = true;
                threadSever_ZX.Start();
                return true;
            }
            catch (Exception)
            {
                return false;
                //toolStripLabel1.Text = "开启错误,请检查IP和端口号!";
            }
        }

		 /// <summary>
        /// 监听函数
        /// </summary>
        private void Listenning_ZX()
        {
            while (IsTcpStart_ZX)
            {
                try
                {
                    Socket linsSocket = socketSever_ZX.Accept();   //;
                    if (ConnectCount_ZX < 1)    //这里做个判断 单设备连接
                    {
                        ConnectCount_ZX++;
                        ClenctSocket_ZX = linsSocket;
                        string client = ClenctSocket_ZX.RemoteEndPoint.ToString();
                        //获取当前 
                        this.Invoke(new Action(() =>
                        {
                            toolStripLabel1.Text = "当前有设备连接:" + client;
                            Set_Textbox_tile_ZX("当前有设备连接:" + client + "  ", Color.Gray);
                        }));
                        Thread thr = new Thread(RecieveMsg_ZX);
                        ThreadList_ZX.Add(thr);
                        thr.IsBackground = true;
                        thr.Start(ClenctSocket_ZX);
                    }
                    else
                    {
                        linsSocket.Close();
                    }
                }
                catch (Exception)
                {
                    throw;
                }
            }
        }


       private byte[] KeepAlive(int onOff, int keepAliveTime, int keepAliveInterval)
        {
            byte[] buffer = new byte[12];
            BitConverter.GetBytes(onOff).CopyTo(buffer, 0);
            BitConverter.GetBytes(keepAliveTime).CopyTo(buffer, 4);
            BitConverter.GetBytes(keepAliveInterval).CopyTo(buffer, 8);
            return buffer;
        }

3. 服务端接受函数

csharp 复制代码
        /// <summary>
        /// 接收函数
        /// </summary>
        /// <param name="socketClient"></param>
        private void RecieveMsg_ZX(object socketClient)
        {
            byte[] arrMsgRec = new byte[1024 * 2];
            StringBuilder builder = new StringBuilder();
            StringBuilder TestBuilder = new StringBuilder();
            Socket scketClient = socketClient as Socket;
            while (IsTcpStart_ZX)
            {
                int length = -1;
                try
                {
                    if (scketClient.Poll(-1, SelectMode.SelectRead))   //判断socket是否掉线
                    {
                        int nRead = scketClient.Receive(arrMsgRec, SocketFlags.Peek);
                        if (nRead == 0)
                        {

                            this.Invoke(new Action(() =>
                            {
                                Set_Textbox_tile_ZX("客服端:" + scketClient.RemoteEndPoint.ToString() + "断开连接   ", Color.Gray);
                            }));
                            ClenctSocket_ZX = null;
                            ConnectCount_ZX = 0;
                            return;
                        }
                        length = scketClient.Receive(arrMsgRec);
                    }
                }
                catch (Exception)
                {
                }

以上就是基本的程序,上面我大概写下,网上教程很多参考下就行了

主要我讲讲这个这个TCP 作为主机 从机掉线这一块

-------首先说说 下面这个方法,如下图所示下面是他的方法说明,这是一个关于Socket的一个状态轮询的函数 这里我们轮询的是接受状态 SelectMode.SelectRead ,就是如下图所说如果 返回结果为 false 则连接处于 已关闭、重置、或者终止状态,前面的参数是等待响应,这里我们就直接触发就行。这个方法能有效检测链路层断线等情况

if (scketClient.Poll(-1, SelectMode.SelectRead)) //判断socket是否掉线


还有就是下面这个方法:

socketSever.IOControl(IOControlCode.KeepAliveValues, KeepAlive(1, 1000, 1000), null);
官方API说明 =================》
网友参考资料1

大家可以参考下! 反正意思基本就发布包 保证连接双方通信正常,不正常时做处理。

相关推荐
STQY燊桐启元(深圳)电子科技7 小时前
医疗精密电源散热方案:相变陶瓷片保障医疗设备长效稳定低干扰
大数据·网络·人工智能
CDN3609 小时前
节点智能调度实操:解决出海区域访问快慢不均、节点拥堵、跨洋延迟高,CDN 全网择优落地方案
运维·服务器·网络
roman_日积跬步-终至千里10 小时前
【数据治理(6)】DataOps 不是调度工具,而是让数据产品长期可信的运行机制
java·服务器·网络
可乐鸡翅yeah_12 小时前
个人 / 外包流媒体项目交付实战,M3U8 验收与问题闭环完整工作流
运维·网络·python·低代码·django·m3u8·在线播放
黄俊懿13 小时前
【架构师从入门到进阶】第五章:DNS&CDN&网关优化思路——第十节:网关安全-单向加密
网络·数据库·计算机网络·安全·架构·系统架构·架构师
Patrick在香港13 小时前
Python 拉取城巴开放数据:406 条路线,香港岛巴士网络的数字画像
网络·python·数据分析·php·数据可视化·香港·开放数据
格林威14 小时前
C# 相机Burst模式图像采集:使用相机内存配合OpenCvSharp和Halcon实现短时间的高速采集的方法
开发语言·人工智能·数码相机·计算机视觉·c#·视觉检测·工业相机
一直C14 小时前
Linux系统编程|进程间通信IPC全套详解(1)(管道、信号)
linux·c语言·开发语言·网络·青少年编程·visual studio code
Experience-摆渡14 小时前
自建 IP 轮换方案实战:健康探测 + 熔断剔除 + 粘性会话
网络·网络协议·tcp/ip
luj_176814 小时前
合法避税与投资评估实战指南
c语言·开发语言·网络·经验分享·算法