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();//斷開掛起的異步連接
            }
        }

    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM