我们知道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}