转载: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;
}

修改后为:

   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();
}
}

V3

客户端代码:

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();
} }
}

客户端代码

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

基于TCP通信的客户端断线重连的更多相关文章

  1. 【TCP/IP网络编程】:04基于TCP的服务器端/客户端

    摘要:结合前面所讲述的知识,本篇文章主要介绍了简单服务器端和客户端实现的框架流程及相关函数接口. 理解TCP和UDP 根据数据传输方式的不同,基于网络协议的套接字一般分为TCP套接字和UDP套接字(本 ...

  2. 基于TCP协议的客户端

    基于TCP协议的客户端 此客户端能用于下一篇博客的单线程服务器和多线程服务器 import java.io.BufferedReader; import java.io.IOException; im ...

  3. TCP通信的客户端代码实现和TCP通信的服务器代码实现

    TCP通信的客户端代码实现 package com.yang.Test.ServerStudy; import java.io.*; import java.net.Socket; /** * TCP ...

  4. Java进阶:基于TCP通信的网络实时聊天室

    目录 开门见山 一.数据结构Map 二.保证线程安全 三.群聊核心方法 四.聊天室具体设计 0.用户登录服务器 1.查看当前上线用户 2.群聊 3.私信 4.退出当前聊天状态 5.离线 6.查看帮助 ...

  5. JAVA基础知识之网络编程——-基于TCP通信的简单聊天室

    下面将基于TCP协议用JAVA写一个非常简单的聊天室程序, 聊天室具有以下功能, 在服务器端,可以接受客户端注册(用户名),可以显示注册成功的账户 在客户端,可以注册一个账号,并用这个账号发送信息 发 ...

  6. 基于TCP的安卓客户端开发

    一.Socket通信简介 Android与服务器的通信方式主要有两种,一是Http通信,一是Socket通信.两者的最大差异在于,http连接使用的是“请求—响应方式”,即在请求时建立连接通道,当客户 ...

  7. java-websocket客户端 断线重连 注入Service问题

    java版客户端: 使用开源项目java-websocket, github地址: https://github.com/TooTallNate/Java-WebSocket github上有很多示例 ...

  8. SignalR控制台自托管服务端向web客户端指定用户推送数据,客户端断线重连

    一.前言 SignalR是微软推出的开源实时通信框架.其内部使用Web Socket, Server Sent Events 和 Long Polling作为底层传输方式,SignalR会根据客户端和 ...

  9. Netty 客户端断线重连

    client 关闭后会执行 finally 代码块,可以在这里可以进行重连操作 public class NettyClient implements Runnable { private final ...

随机推荐

  1. Window Server 2008 R2 安装 Share Point 2013

    原文地址:http://www.cnblogs.com/jianyus/p/3631905.html

  2. 22:django 配置详解

    django配置文件包含了你的django安装的所有配置信息,本节为大家详细讲解django的配置 基本知识 一个配置文件只是一个包含模块级别变量的的python模块,所有的配置变量都是大写的,哈哈哈 ...

  3. review的一个收获popstate,addEventListener:false ,split,jquery cache

    一.popstate:记录url历史变化 二.document.location.hash:锚点后面的东西 三.addEventListener:false 是否在捕获或者冒泡事件中执行 强转换 四. ...

  4. Oracle中的case when then else end 应用

    Case when 的用法,简单Case函数 简单CASE表达式,使用表达式确定返回值. 语法: CASE search_expression WHEN expression1 THEN result ...

  5. DuplicateHandle

    功能:将一个进程内的伪句柄,转化为可以用来进程间通信的实句柄 BOOL DuplicateHandle(  HANDLE hSourceProcessHandle,  HANDLE hSourceHa ...

  6. git在window与linux的换行符问题

    1:背景.我win7,后端是win10,使用了TortoiseGit工具.我使用ssh,他使用http.仓库是在linux,使用gitLab管理 2:问题.仓库是总监之前建好的.后端把文件add后pu ...

  7. 微信小程序-ios系统-下拉上拉出现白色,如何处理呢?

    这几天做小程序,有些页面都是全屏的背景,在安卓上背景是固定的,而在ios上上拉下拉出现白色,测试说体验不太好,一开始我以为是下拉上拉刷新造成的,关闭了依然是这样.为了体验好点,可以按一下解决: 方式一 ...

  8. C#获取网页信息核心方法(入门一)

    目录:信息采集入门系列目录 下面记录的是我自己整理的C#请求页面核心类,主要有如下几个方法 1.HttpWebRequest Get请求获得页面html 2.HttpWebRequest Post请求 ...

  9. NET应用——你的数据安全有必要升级

    最近又被[现场破解共享单车系统]刷了一脸,不得不开始后怕:如何防止类似的情况发生? 想来想去,始终觉得将程序加密是最简单的做法.但是摩拜.ofo也有加密,为什么仍然被破解?那是因为请求在传输过程中被篡 ...

  10. 洛谷P3975 跳房子 [DP,单调队列优化,二分答案]

    题目传送门 跳房子 题目描述 跳房子,也叫跳飞机,是一种世界性的儿童游戏,也是中国民间传统的体育游戏之一. 跳房子的游戏规则如下: 在地面上确定一个起点,然后在起点右侧画 n 个格子,这些格子都在同一 ...