C# Socket之异步TCP客户端断线重连
我们知道TCP通信是一种面向连接的Socket,针对于面向连接的TCP服务应用,安全,但是效率低,它首先需要服务端开启服务,然后客户端才可以去连接,如果服务端没有开启通信服务或者连接之后再中途因为某些原因断开连接了,那么都是会通信失败的,所以我们这篇博客主要是对TCP通信加入两个机制。1,客户端开启后未连接成功,自动重连请求 2,若通信途中因为某些原因断开连接了自动重连机制 因为测试发现如果是程序运行途中我们利用同步的方式重新连接的话连接时会出现程序卡顿的情况,这个对用户的体验是非常不好的,为了避免这个情况,我们采用的是异步TCP通信的方式,代码如下,这是一个单例脚本,无需挂载,程序开始时调用一下ConnectServer方法开启通信就好,记得关闭程序时要调用一下Close方法来断开挂起的异步连接,否则调试的时候通信会一直保存着。
/*********************************** * Description:异步TCP客户端 * Mountpoint:这是一个单例脚本,无需挂载,直接调用即可 * Date:2019.06.25 * Version:unity版本2017.2.0f3 * Author:LJF ***********************************/ using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Net; using System.Net.Sockets; using System; using System.Text; namespace LJF { //规范命名、添加注释、合理封装、限制访问权限 public class AsyncTcpClient { private string ip1; private int port1; byte[] ReadBytes = new byte[1024 * 1024]; //单例 public static AsyncTcpClient Instance { get { if (instance==null) { instance = new AsyncTcpClient(); } return instance; } } private static AsyncTcpClient instance; System.Net.Sockets.TcpClient tcpClient; //连接服务器 public void ConnectServer(string ip, int port)//填写服务端IP与端口 { //Debuger.EnableSave = true; ip1 = ip; port1 = port; try { tcpClient = new System.Net.Sockets.TcpClient();//构造Socket tcpClient.BeginConnect(IPAddress.Parse(ip), port,Lianjie, null);//开始异步 } catch (Exception e) { Debug.Log(e.Message); } } //连接判断 void Lianjie(IAsyncResult ar) { if (!tcpClient.Connected) { Debug.Log("服务器未开启,尝试重连。。。。。。"); tcpClient.BeginConnect(IPAddress.Parse(ip1), port1, Lianjie, null); //IAsyncResult rest = tcpClient.BeginConnect(IPAddress.Parse(ip1), port1, Lianjie, null); //bool scu= rest.AsyncWaitHandle.WaitOne(3000); } else { Debug.Log("连接上了"); tcpClient.EndConnect(ar);//结束异步连接 tcpClient.GetStream().BeginRead(ReadBytes, 0, ReadBytes.Length, ReceiveCallBack, null); } } //接收消息 void ReceiveCallBack(IAsyncResult ar) { try { int len = tcpClient.GetStream().EndRead(ar);//结束异步读取 if (len > 0) { string str = Encoding.UTF8.GetString(ReadBytes, 0,len); str = Uri.UnescapeDataString(str); //将接收到的消息写入日志 //Debuger.Log(string.Format("收到主机:{0}发来的消息|{1}", ip1, str)); //Debug.Log(str); tcpClient.GetStream().BeginRead(ReadBytes, 0, ReadBytes.Length, ReceiveCallBack, null); } else { tcpClient = null; Debug.Log("连接断开,尝试重连。。。。。。"); ConnectServer(ip1,port1); } } catch (Exception e) { Debug.Log(e.Message); } } //发送消息 public void SendMsg(string msg) { byte[] msgBytes = Encoding.UTF8.GetBytes(msg); tcpClient.GetStream().BeginWrite(msgBytes, 0, msgBytes.Length, (ar) => { tcpClient.GetStream().EndWrite(ar);//结束异步发送 }, null);//开始异步发送 } /// <summary> /// 断开连接 /// </summary> public void Close() { if (tcpClient != null && tcpClient.Client.Connected) tcpClient.Close(); if (!tcpClient.Client.Connected) { tcpClient.Close();//断开挂起的异步连接 } } } }