TCP客户端断线重连-升级版
解决拔掉网线后无法快速诊断是否掉线问题
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System;
using System.Text;
using System.Diagnostics;
using System.Net.NetworkInformation;
using System.Threading.Tasks;
using System.Threading;namespace MyTcpClient
{//规范命名、添加注释、合理封装、限制访问权限 public class AsyncTcpClient{private string ip1;private int port1;private byte[] ReadBytes = new byte[1024];//单例private TcpClient tcpClient;//连接服务器public void ConnectServer(string ip, int port){//防止多个事例去重复连接if (isTryingToCon == true){return;}ip1 = ip;port1 = port;try{if (tcpClient != null){tcpClient.Close();}tcpClient = new TcpClient();isTryingToCon = true;//开始异步tcpClient.BeginConnect(IPAddress.Parse(ip), port, Lianjie, null);}catch (Exception e){}}private bool isTryingToCon = false;//连接判断private void Lianjie(IAsyncResult ar){if (IsClose){return;}try{if (tcpClient.Connected == false){SetCon(0);tcpClient.Close();tcpClient = new System.Net.Sockets.TcpClient();//尝试重连。。。。。。;tcpClient.BeginConnect(IPAddress.Parse(ip1), port1, Lianjie, null);}else{tcpClient.Client.IOControl(IOControlCode.KeepAliveValues, KeepAlive(1, 500, 500), null);//连接上了isTryingToCon = false;//结束异步连接tcpClient.EndConnect(ar);//读取数据tcpClient.GetStream().BeginRead(ReadBytes, 0, ReadBytes.Length, ReceiveCallBack, null);SetCon(1);}}catch (Exception){}}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;}//接收消息private void ReceiveCallBack(IAsyncResult ar){try{int len = tcpClient.GetStream().EndRead(ar);//结束异步读取if (len > 0){MyEventArgs e = new MyEventArgs(ip1, ReadBytes);_MsgChange(e);//重置数据,防止旧数据残留ReadBytes = new byte[512];tcpClient.GetStream().BeginRead(ReadBytes, 0, ReadBytes.Length, ReceiveCallBack, null);}else{//尝试重连。。。。。。"ConnectServer(ip1, port1);}}catch (Exception e){}}//发送消息public bool SendMsg(string msg){//发送XXXX0001_000000000000_ (没有下划线) //接收00570002_000000000000_010001020103try{//数据部分byte[] bt_Data = Encoding.ASCII.GetBytes(msg);byte[] bt_head = Encoding.ASCII.GetBytes((bt_Data.Length + 4).ToString("0000"));byte[] bt_send = new byte[bt_Data.Length + 4];for (int i = 0; i < bt_head.Length; i++){bt_send[i] = bt_head[i];}for (int i = 0; i < bt_Data.Length; i++){bt_send[i + 4] = bt_Data[i];}//开始异步发送try{tcpClient.GetStream().BeginWrite(bt_send, 0, bt_send.Length, (ar) =>{tcpClient.GetStream().EndWrite(ar);//结束异步发送}, null);}catch (Exception ex){string abc = ex.ToString();}return true;}catch (Exception ex){SetCon(-1);SetCon(0);// int a = ex.NativeErrorCode;//尝试重连。。。。。。"ConnectServer(ip1, port1);return false;}}public bool SendMsg(byte[] msg){try{//开始异步发送tcpClient.GetStream().BeginWrite(msg, 0, msg.Length, (ar) =>{tcpClient.GetStream().EndWrite(ar);//结束异步发送}, null);return true;}catch (Exception ex){//尝试重连。。。。。。"SetCon(-1);SetCon(0);ConnectServer(ip1, port1);return false;}}bool IsClose = false;/// <summary>/// 断开连接/// </summary>public void Close(){IsClose = true;if (tcpClient != null && (tcpClient.Client == null || tcpClient.Client.Connected)){tcpClient.Close();}}public int isConnected = -1;/// <summary>/// -1 初始化 0 未连接 1 连接/// </summary>/// <param name="_con"></param>private void SetCon(int _con){if (isConnected != _con){bool rel = false;if (_con == 1){rel = true;}isConnected = _con;MyEventArgs e = new MyEventArgs(ip1 + "__" + port1.ToString(), rel);_ConChange(e);}}public void StarPing(){Task.Factory.StartNew(() => PingOC());}private void PingOC(){Ping ping = new Ping();while (!IsClose){try{PingReply pingReply = ping.Send(ip1, 1000);//网络状态if (pingReply.Status != IPStatus.Success){SetCon(-1);SetCon(0);ConnectServer(ip1, port1);}Thread.Sleep(1000);}catch (Exception){}}}public class MyEventArgs : EventArgs{public string IP;public bool IsConnetct;public byte[] Msg;public MyEventArgs(string iP, byte[] msg){IP = iP;Msg = msg;}public MyEventArgs(string iP, bool iscon){IP = iP;IsConnetct = iscon;}}//连接状态public delegate void ConChange(object sender, MyEventArgs args);public event ConChange OnConChange;protected virtual void _ConChange(MyEventArgs e){if (OnConChange != null){OnConChange(this, e);}}//收到的消息public delegate void MsgChange(object sender, MyEventArgs args);public event MsgChange OnMsgChange;protected virtual void _MsgChange(MyEventArgs e){if (OnMsgChange != null){OnMsgChange(this, e);}}}
}
调用方法:
AsyncTcpClient sw = new AsyncTcpClient(); sw.ConnectServer("192.168.1.1", 4545);sw.OnConChange += Sw_OnConChange;sw.OnMsgChange += Sw_OnMsgChange;sw.StarPing();private void Sw_OnConChange(object sender, AsyncTcpClient.MyEventArgs args){if (args.IsConnetct){//已连接}else{//已断开}
}private void Sw_OnMsgChange(object sender, AsyncTcpClient.MyEventArgs args){//接收的信息string str = Encoding.ASCII.GetString(args.Msg, 0, args.Msg.Length);str = Uri.UnescapeDataString(str).Replace("\0", "");}public void CloseTcp(){sw.OnConChange -= Sw_OnConChange;sw.OnMsgChange -= Sw_OnMsgChange;sw.Close();}
TCP客户端断线重连-升级版相关推荐
- Socket编程概念和 Socket之异步TCP客户端断线重连
一:什么是SOCKET socket的英文原义是"孔"或"插座".作为进程通信机制,取后一种意思.通常也称作"套接字",用于描 ...
- Netty客户端断线重连实现及问题思考
点击关注公众号,利用碎片时间学习 前言 在实现TCP长连接功能中,客户端断线重连是一个很常见的问题,当我们使用netty实现断线重连时,是否考虑过如下几个问题: 如何监听到客户端和服务端连接断开 ? ...
- Labview 编写TCP/IP 客户端断线重连机制程序,亲测可用
程序面板如下图: 此程序支持任意一方断线重连机制,仅供大家参考! 实际工程中,如果出现服务器出现宕机,那么我们的客户端要有重连的机制,不然软件不会自动连接服务器,明显是我们程序编写的一个漏洞,无论是从 ...
- springboot集成websocket(一)客户端、客户端断线重连、客户端连接验证
springboot集成websocket客户端 一.首先是导入依赖包 1.在pom.xml中加入下述即可 <!--websocket作为客户端 --><dependency> ...
- go tcp客户端自动重连_在Go中构建并发TCP服务器样例
开发一个并发TCP服务器,只使用大约65行Go代码生成随机数. 本文是Mihalis Tsoukalos的Go系列的一部分.阅读第1部分:在Go中创建随机安全密码. TCP和UDP服务器无处不在,通过 ...
- go tcp客户端自动重连_阿里面试: HTTP、HTTPS、TCP/IP、三次握手四次挥手过程?(附全网最具深度讲解)
前言 这段时间面试官都挺忙的,频频出现在博客文章标题,虽然我不是特别想蹭热度,但是实在想不到好的标题了-.-,蹭蹭就蹭蹭 :) 事实上我在阿里面试的时候确实被问到了这个问题,HTTP.HTTPS.TC ...
- go tcp客户端自动重连_使用 Go 语言创建 WebSocket 服务
今天介绍如何用 Go 语言创建 WebSocket 服务,文章的前两部分简要介绍了 WebSocket 协议以及用 Go 标准库如何创建 WebSocket 服务.第三部分实践环节我们使用了 gori ...
- go tcp客户端自动重连_深入分析TCP的keepalive和time_wait,总能发现新东西
TCP是一个有状态通讯协议,所谓的有状态是指通信过程中通信的双方各自维护连接的状态. 一.TCP keepalive 先简单回顾一下TCP连接建立和断开的整个过程.(这里主要考虑主流程,关于丢包.拥塞 ...
- Netty是如何实现TCP心跳机制与断线重连的
本文来说下Netty 是如何实现 TCP 心跳机制与断线重连的 文章目录 什么是心跳机制HeartBeat 如何实现心跳机制 Netty实现自定义的心跳机制 服务端 客户端 测试效果 客户端断线重连 ...
最新文章
- module ‘torchtext.data‘ has no attribute ‘LabelField‘
- scala成长之路(2)对象和类
- Android学习笔记之SoftReference软引用,弱引用WeakReference
- 新概念0820:我只有一种生活
- 拷贝了虚拟机后linux下如何配置静态ip,并连接外网
- 使用OmniDB数据库管理工具,管理Oracle/MariaDB/PostgreSQL等关系型数据库
- Doc2vec在推荐系统中的应用(含算法原理、代码实现)
- (转)VC 字节对齐
- php api查询开发,PHP 开发API接口 登记,登录,查询用户资料
- Docker使用小结(四)发布镜像
- 计算机与网络教育缺点,互联网安全有什么类型,缺点在何处?
- linux下安装oracle instant client,linux下安装Oracle instant client
- excel常用函数及快捷键
- 人工智能的数学基础------- 矩阵迹与相似矩阵的本质
- 11月全国程序员平均工资出炉,我给同行丢脸了。。。
- 民科微服务小程序怎么注册_民科微服务小程序app个人端认证下载-民科微服务小程序登录官方入口下载v2.4最新版_289手游网...
- 【新书推荐】【2017.07】创新的雷达技术与应用第一卷:实孔径阵列雷达、成像雷达与无源多基地雷达
- 股票买卖接口如何实现委托下单的功能?
- delphi 获取打印机默认纸张_Delphi中如何控制打印方向,纸张大小等 | 学步园
- 应用商店上架被拒解决办法
热门文章
- 深聊MySQL,从入门到入坟之:MySQL竟然也有后悔药!!!
- VMware Site Recovery Manager 8.5 下载 - 数据中心灾难恢复 (DR)
- TikTok Store 商店卖家上船 官方说明
- java学习路线---大师级的,我看了明白多了
- C语言指针学习(1)
- 网络状态是一条横线 连接不上网络的解决办法
- Driver residency in WDDM 2.0(MSDN翻译)
- .net的winform中DialogResult属性的使用
- VIP1 冰霜区 神翼天使,真的很杯具
- shader冰冻效果