C# Socket之异步TCP客户端断线重连

  我们知道TCP通信是一种面向连接的Socket,针对于面向连接的TCP服务应用,安全,但是效率低,它首先需要服务端开启服务,然后客户端才可以去连接,如果服务端没有开启通信服务或者连接之后再中途因为某些原因断开连接了,那么都是会通信失败的,所以我们这篇博客主要是对TCP通信加入两个机制。1,客户端开启后未连接成功,自动重连请求 2,若通信途中因为某些原因断开连接了自动重连机制  因为测试发现如果是程序运行途中我们利用同步的方式重新连接的话连接时会出现程序卡顿的情况,这个对用户的体验是非常不好的,为了避免这个情况,我们采用的是异步TCP通信的方式,代码如下,这是一个单例脚本,无需挂载,程序开始时调用一下ConnectServer方法开启通信就好,记得关闭程序时要调用一下Close方法来断开挂起的异步连接,否则调试的时候通信会一直保存着。

1/*********************************** 2* Description:异步TCP客户端 3* Mountpoint:这是一个单例脚本,无需挂载,直接调用即可 4* Date:2019.06.25 5* Version:unity版本2017.2.0f3 6* Author:LJF 7***********************************/ 8using System.Collections; 9using System.Collections.Generic; 10using UnityEngine; 11using System.Net; 12using System.Net.Sockets; 13using System; 14using System.Text; 15 16 17namespace LJF 18{ 19 //规范命名、添加注释、合理封装、限制访问权限 20 public class AsyncTcpClient 21 { 22 private string ip1; 23 private int port1; 24 byte[] ReadBytes = new byte[1024 * 1024]; 25 //单例 26 public static AsyncTcpClient Instance 27 { 28 get 29 { 30 if (instance==null) 31 { 32 instance = new AsyncTcpClient(); 33 } 34 return instance; 35 } 36 } 37 private static AsyncTcpClient instance; 38 39 System.Net.Sockets.TcpClient tcpClient; 40 41 //连接服务器 42 public void ConnectServer(string ip, int port)//填写服务端IP与端口 43 { 44 //Debuger.EnableSave = true; 45 ip1 = ip; 46 port1 = port; 47 try 48 { 49 tcpClient = new System.Net.Sockets.TcpClient();//构造Socket 50 tcpClient.BeginConnect(IPAddress.Parse(ip), port,Lianjie, null);//开始异步 51 } 52 catch (Exception e) 53 { 54 Debug.Log(e.Message); 55 } 56 } 57 58 //连接判断 59 void Lianjie(IAsyncResult ar) 60 { 61 if (!tcpClient.Connected) 62 { 63 Debug.Log("服务器未开启,尝试重连。。。。。。"); 64 tcpClient.BeginConnect(IPAddress.Parse(ip1), port1, Lianjie, null); 65 //IAsyncResult rest = tcpClient.BeginConnect(IPAddress.Parse(ip1), port1, Lianjie, null); 66 //bool scu= rest.AsyncWaitHandle.WaitOne(3000); 67 } 68 else 69 { 70 Debug.Log("连接上了"); 71 tcpClient.EndConnect(ar);//结束异步连接 72 tcpClient.GetStream().BeginRead(ReadBytes, 0, ReadBytes.Length, ReceiveCallBack, null); 73 } 74 } 75 76 77 //接收消息 78 void ReceiveCallBack(IAsyncResult ar) 79 { 80 try 81 { 82 int len = tcpClient.GetStream().EndRead(ar);//结束异步读取 83 if (len > 0) 84 { 85 86 string str = Encoding.UTF8.GetString(ReadBytes, 0,len); 87 str = Uri.UnescapeDataString(str); 88 //将接收到的消息写入日志 89 //Debuger.Log(string.Format("收到主机:{0}发来的消息|{1}", ip1, str)); 90 //Debug.Log(str); 91 tcpClient.GetStream().BeginRead(ReadBytes, 0, ReadBytes.Length, ReceiveCallBack, null); 92 } 93 else 94 { 95 tcpClient = null; 96 Debug.Log("连接断开,尝试重连。。。。。。"); 97 ConnectServer(ip1,port1); 98 } 99 } 100 catch (Exception e) 101 { 102 Debug.Log(e.Message); 103 } 104 } 105 106 //发送消息 107 public void SendMsg(string msg) 108 { 109 byte[] msgBytes = Encoding.UTF8.GetBytes(msg); 110 tcpClient.GetStream().BeginWrite(msgBytes, 0, msgBytes.Length, (ar) => { 111 tcpClient.GetStream().EndWrite(ar);//结束异步发送 112 }, null);//开始异步发送 113 } 114 115 /// <summary> 116 /// 断开连接 117 /// </summary> 118 public void Close() 119 { 120 if (tcpClient != null && tcpClient.Client.Connected) 121 tcpClient.Close(); 122 if (!tcpClient.Client.Connected) 123 { 124 tcpClient.Close();//断开挂起的异步连接 125 } 126 } 127 128 } 129}
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

java学习 网络编程 tcp

有客户端和服务端,使用tcp传输day26 27//客户端发数据到服务端/\\Tcp传输,客户端建立的过程。\1,创建tcp客户端socket服务。使用的是Socket对象。\建议该对象一创建就明确目的地。要连接的主机。\2,如果连接建立成功,说明数据传输通道已建立。\该通道就是socket流

Android Socket 通信

Androidsocket通信安卓编写Socket客户端,实现连接Socket服务端通信。创建Socket连接并获取服务端数据先创建几个全局变量吧privateBufferedWriterwriternull;Socketsocket;