基于TCP通信的客户端断线重连
转载: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通信的客户端断线重连的更多相关文章
- 【TCP/IP网络编程】:04基于TCP的服务器端/客户端
摘要:结合前面所讲述的知识,本篇文章主要介绍了简单服务器端和客户端实现的框架流程及相关函数接口. 理解TCP和UDP 根据数据传输方式的不同,基于网络协议的套接字一般分为TCP套接字和UDP套接字(本 ...
- 基于TCP协议的客户端
基于TCP协议的客户端 此客户端能用于下一篇博客的单线程服务器和多线程服务器 import java.io.BufferedReader; import java.io.IOException; im ...
- TCP通信的客户端代码实现和TCP通信的服务器代码实现
TCP通信的客户端代码实现 package com.yang.Test.ServerStudy; import java.io.*; import java.net.Socket; /** * TCP ...
- Java进阶:基于TCP通信的网络实时聊天室
目录 开门见山 一.数据结构Map 二.保证线程安全 三.群聊核心方法 四.聊天室具体设计 0.用户登录服务器 1.查看当前上线用户 2.群聊 3.私信 4.退出当前聊天状态 5.离线 6.查看帮助 ...
- JAVA基础知识之网络编程——-基于TCP通信的简单聊天室
下面将基于TCP协议用JAVA写一个非常简单的聊天室程序, 聊天室具有以下功能, 在服务器端,可以接受客户端注册(用户名),可以显示注册成功的账户 在客户端,可以注册一个账号,并用这个账号发送信息 发 ...
- 基于TCP的安卓客户端开发
一.Socket通信简介 Android与服务器的通信方式主要有两种,一是Http通信,一是Socket通信.两者的最大差异在于,http连接使用的是“请求—响应方式”,即在请求时建立连接通道,当客户 ...
- java-websocket客户端 断线重连 注入Service问题
java版客户端: 使用开源项目java-websocket, github地址: https://github.com/TooTallNate/Java-WebSocket github上有很多示例 ...
- SignalR控制台自托管服务端向web客户端指定用户推送数据,客户端断线重连
一.前言 SignalR是微软推出的开源实时通信框架.其内部使用Web Socket, Server Sent Events 和 Long Polling作为底层传输方式,SignalR会根据客户端和 ...
- Netty 客户端断线重连
client 关闭后会执行 finally 代码块,可以在这里可以进行重连操作 public class NettyClient implements Runnable { private final ...
随机推荐
- 移动端测试===安卓设备共享程序-发布版本“share device”
分享一个开源的项目 share device 项目地址:https://github.com/sunshine4me/ShareDevicePublish/tree/win7-x64 首先选择对应系统 ...
- 用intellj 建一个spring mvc 项目DEMO
spring的起初可能经常碰壁,因为网上的资料都是混乱的xml堆成的,混乱难以理解,我这个也是,阿哈哈哈哈! 新建一个Maven->create from archetype->org.j ...
- PHP下载APK文件
PHP下载APK文件(代码如下) /** * //这里不要随便打印文字,否则会影响输出的文件的 * (例如下载没问题,但是apk安装时候提醒解析安装包错误) * @return array */ pu ...
- Tensorflow项目实战一:MNIST手写数字识别
此模型中,输入是28*28*1的图片,经过两个卷积层(卷积+池化)层之后,尺寸变为7*7*64,将最后一个卷积层展成一个以为向量,然后接两个全连接层,第一个全连接层加一个dropout,最后一个全连接 ...
- java web 资源文件读取
前提:假设web应用test(工程名) webapps下面有一资源文件test.html 规则:在获取资源时一般使用的是相对路径,以符号/开头,而 / 代表什么取决于这个地址给谁使用.服务器使用时,/ ...
- CSS中cursor属性给标签加上小手形状
HTML/CSS 2012-08-10 CSS,标签 我们发现a标签在网页中有一个值得注意的地方,即鼠标移到a标签上光标会变成一只小手的图标,移出a标签后又恢复为默认箭头. 如今,JS在网页中的功能越 ...
- POJ 1160 Post Office(DP+经典预处理)
题目链接:http://poj.org/problem?id=1160 题目大意:在v个村庄中建立p个邮局,求所有村庄到它最近的邮局的距离和,村庄在一条直线上,邮局建在村庄上. 解题思路:设dp[i] ...
- LeetCode212. Word Search II
https://leetcode.com/problems/word-search-ii/description/ Given a 2D board and a list of words from ...
- Restful Framework (四)
目录 一.分页 二.视图 三.路由 四.渲染器 一.分页 回到顶部 试问如果当数据量特别大的时候,你是怎么解决分页的? 方式a.记录当前访问页数的数据id 方式b.最多显示120页等 方式c.只显示上 ...
- hdu 1505(最大子矩阵)
City Game Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total S ...