基于TCP通信的客户端断线重连

简介: 转载:http://www.cnblogs.com/networkcomms/p/4304362.html 源码下载 在CS程序中,断线重连应该是一个常见的功能。 此处的断线重连主要指的是服务器端因为某种故障,服务器端程序或者系统进行了重新启动,客户端能够自动探测到服务器端掉线,并尝试重新进行连接 本程序基于来自英国的开源c#通信框架的networkcomms(2.

转载:http://www.cnblogs.com/networkcomms/p/4304362.html

源码下载

在CS程序中,断线重连应该是一个常见的功能。

此处的断线重连主要指的是服务器端因为某种故障,服务器端程序或者系统进行了重新启动,客户端能够自动探测到服务器端掉线,并尝试重新进行连接

本程序基于来自英国的开源c#通信框架的networkcomms(2.3.1版本)

先看一下效果

初始状态:

当服务器端程序关闭后,客户端会自动探测到,并在客户端显示相关信息

然后,我们设定为每隔5秒重连一次,可以自定义设置重连的次数,比如说重连50次,如果还没有重连成功,则放弃重连

然后我们重新启动服务器端,客户端会显示重连成功.

具体步骤如下:

需要修改几处NetworkComms2.3.1通信框架中的代码

第一步:修改ConnectionInfo类的NoteConnectionShutdown方法

该方法原来是:

   internal void NoteConnectionShutdown()
        {
            lock (internalLocker)
                ConnectionState = ConnectionState.Shutdown; }
View Code

修改后为: 

复制代码
   private bool reconnectFlag = false;
        /// <summary> /// 是否为重连接模式 /// </summary> public bool ReconnectFlag { get { return reconnectFlag; } set { reconnectFlag = value; } } /// <summary> /// Note this connection as shutdown /// </summary> internal void NoteConnectionShutdown() { lock (internalLocker) ConnectionState = ConnectionState.Shutdown; //添加以下代码 初始状态为False 触发连接状态改变事件 if (reconnectFlag == false) { StateChanged.Raise(this, new StringEventArgs("连接出现异常")); } } //添加状态改变事件 public event EventHandler<StringEventArgs> StateChanged;
复制代码

 

第二步:在NetworkComms库类中添加相关的代码如下:

using System;
using System.Collections.Generic;
using System.Text; using NetworkCommsDotNet.Tools; namespace NetworkCommsDotNet { public static class Extensions { public static void Raise<T>(this EventHandler<T> handler, object sender, T args) where T : EventArgs { if (handler != null) handler(sender, args); } } public class StringEventArgs : EventArgs { public StringEventArgs(string text) { Text = text; } public string Text { get; set; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly)] public sealed class ExtensionAttribute : Attribute { } }
相关代码

第三步:在NetworkComms静态类中添加如下方法:

复制代码
 public static void ClearDic()
        {
            lock (globalDictAndDelegateLocker) { allConnectionsById.Clear(); allConnectionsByEndPoint.Clear(); oldNetworkIdentifierToConnectionInfo.Clear(); } }
复制代码

如果您使用的是V3版本,代码稍微变化:

复制代码
 public static void ClearDic()
        {
            lock (globalDictAndDelegateLocker) { allConnectionsByIdentifier.Clear(); allConnectionsByEndPoint.Clear(); oldNetworkIdentifierToConnectionInfo.Clear(); } }
复制代码

客户端代码:

复制代码
using System;
using System.Collections.Generic;
using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using NetworkCommsDotNet; using DPSBase; using System.Net; using System.Threading; namespace AppClient { public partial class Form1 : Form { //连接信息类 public ConnectionInfo connnectionInfo = null; //连接类  Connection connection; public Form1() { InitializeComponent(); } //在窗体上显示新信息 void Form_ConnectionStatusNotify(object sender, StringEventArgs e) { if (this.InvokeRequired) { this.Invoke(new EventHandler<StringEventArgs>(this.Form_ConnectionStatusNotify), sender, e); } else { lblLink.Text = e.Text; lblLink.ForeColor = Color.Blue; } } private bool ServerNotifyClose = false; public event EventHandler<StringEventArgs> ConnectionStatusNotify; void connnectionInfo_StateChanged(object sender, StringEventArgs e) { //如果不是服务器通知关闭,则自动重连,如果是服务器通知关闭,则不作处理 //本Demo中没有使用ServerNotifyClose if (ServerNotifyClose == false) { //更新连接信息类 设置为重连模式 connnectionInfo.ReconnectFlag = true; ConnectionStatusNotify.Raise(this, new StringEventArgs("可能由于服务器的故障,与服务器端的连接已断开")); int num = 0; int retryCount = 30; int retrySpanInMSecs = 5000; do { try { NetworkComms.ClearDic(); connection = TCPConnection.GetConnection(connnectionInfo); ConnectionStatusNotify.Raise(this, new StringEventArgs("重连成功")); connnectionInfo.ReconnectFlag = false; break; } catch (Exception ex) { num++; if (num < retryCount) { ConnectionStatusNotify.Raise(this, new StringEventArgs("正在进行第" + num + "次重连")); Thread.Sleep(retrySpanInMSecs); } } } while (num < retryCount); } } private void button1_Click(object sender, EventArgs e) { connnectionInfo = new ConnectionInfo(txtIP.Text, int.Parse(txtPort.Text)); //如果不成功,会弹出异常信息 connection = TCPConnection.GetConnection(connnectionInfo); button1.Enabled = false; button1.Text = "连接成功"; //订阅连接信息类中的连接状态改变事件 connnectionInfo.StateChanged += new EventHandler<StringEventArgs>(connnectionInfo_StateChanged); this.ConnectionStatusNotify += new EventHandler<StringEventArgs>(Form_ConnectionStatusNotify); } //获取水果相关信息 private void button2_Click(object sender, EventArgs e) { if (listBox1.SelectedIndex > -1) { string resMsg = connection.SendReceiveObject<string>("ReqFruitEngName", "ResFruitEngName", 5000, listBox1.Text); MessageBox.Show("您选择的水果的英文名称是:" + resMsg); } else { MessageBox.Show("请选择一项"); } } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { this.Dispose(); } } }
复制代码

服务器端无需额外的设置。

目录
相关文章
|
网络协议 物联网 开发者
NB-IoT 通信之 TCP 收发数据 | 学习笔记
快速学习 NB-IoT 通信之 TCP 收发数据
794 0
NB-IoT 通信之 TCP 收发数据 | 学习笔记
|
4月前
|
网络协议 安全 Java
Java网络编程入门指南:TCP/IP协议与Socket通信
Java网络编程入门指南:TCP/IP协议与Socket通信
55 1
|
6月前
|
SQL 网络协议 前端开发
🚀超级简单的图解TCP/IP,看不懂来打我:OSI模型与通信示例🚀
🚀超级简单的图解TCP/IP,看不懂来打我:OSI模型与通信示例🚀
|
监控 网络协议 安全
一文了解HTTP、HTTPS、TCP、UDP、Websocket(论点:概念、通信流程、异同点、应用领域)
一文了解HTTP、HTTPS、TCP、UDP、Websocket(论点:概念、通信流程、异同点、应用领域)
|
网络协议
海思3559万能平台搭建:TCP客户端网口编程
海思3559万能平台搭建:TCP客户端网口编程
118 0
|
网络协议 Java
Java BIO tcp服务端向客户端消息群发代码教程实战
java BIO tcp服务端向客户端消息群发代码教程实战
124 0
Java BIO tcp服务端向客户端消息群发代码教程实战
|
网络协议
Netty实现TCP通信
Netty实现TCP通信
|
缓存 网络协议 Java
在项目中使用Curator的Java 客户端搭建后进行长TCP连接和TCP权限配置【Zookeeper】
在项目中使用Curator的Java 客户端搭建后进行长TCP连接和TCP权限配置【Zookeeper】
257 0
在项目中使用Curator的Java 客户端搭建后进行长TCP连接和TCP权限配置【Zookeeper】
|
网络协议
TCP编程中的客户端与服务端的通信实现
TCP编程中的客户端与服务端的通信实现
107 0
|
网络协议 Unix Linux
linux网络编程(三) TCP通信时序与多进程/线程并发服务器的编写
linux网络编程(三) TCP通信时序与多进程/线程并发服务器的编写
279 0
linux网络编程(三) TCP通信时序与多进程/线程并发服务器的编写