| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367 | using System;using System.IO;using System.IO.Compression;using System.Net;using System.Net.Sockets;using System.Threading;using Fort23.Core;using Fort23.UTool;using Task = System.Threading.Tasks.Task;namespace Core.KCPTool{    public class TCPClient : IClientConnection    {        private byte[] buffData = new byte[6553];        private Socket socket;        public bool IsConnection { get; set; }        public bool disconnect { get; set; }        //记录半包数据        private bool isBufferData;        private byte[] lastBuffData;        private int lastCount;        private byte lastSendType;        //数据结束        //尾包        private byte[] weiBaoBuffData;        private Thread _udpClientThread;        private IClient client;        private long playerId;        private bool isFinish;        public bool isAwaitReConnect { get; set; }        private bool isStartConnect;        private CTask _cTask;        public bool serveError;               public TCPClient()        {        }        public async Task Connect(IPEndPoint endPoint, long playerId, IClient client)        {            if (isStartConnect)            {                return;            }            serveError = false;            _cTask = CTask.Create(false);            isStartConnect = true;            this.client = client;            this.playerId = playerId;            try            {                socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);                await socket.ConnectAsync(endPoint);                isStartConnect = false;            }            catch (Exception e)            {                disconnect = true;                LogTool.Exception(e);                isStartConnect = false;                serveError = true;                return;            }            IsConnection = false;                        disconnect = false;            _udpClientThread = new Thread(TheUpdate);            _udpClientThread.Start();            byte[] data = SocketTool.LongToByte(playerId);            SendToServer(SendDataType.ShakeHands, data);            await _cTask;        }        /// <summary>        /// 重新链接        /// </summary>        public async void ReConnect(IPEndPoint endPoint, int gameFrame)        {            // if (isStartConnect)            // {            //     return;            // }            //            // if (socket != null)            // {            //     socket.Dispose();            //     socket = null;            // }            //            // isStartConnect = true;            // Thread.Sleep(10);            // LogTool.Error("开始重新链接" + gameFrame);            //            // try            // {            //     socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);            //     await socket.ConnectAsync(endPoint);            //     isStartConnect = false;            // }            // catch (Exception e)            // {            //     disconnect = true;            //     LogTool.Exception(e);            //     isStartConnect = false;            //     return;            // }            //            // disconnect = false;            // _udpClientThread = new Thread(TheUpdate);            // _udpClientThread.Start();            // isAwaitReConnect = true;            byte[] data = SocketTool.LongToByte(playerId);            byte[] gameFrameByte = SocketTool.IntToByte(gameFrame);            byte[] buffer = new byte[data.Length + gameFrameByte.Length];            Array.Copy(data, 0, buffer, 0, data.Length);            Array.Copy(gameFrameByte, 0, buffer, data.Length, gameFrameByte.Length);            SendToServer(SendDataType.GetGameFrameByte, buffer);        }        private void TheUpdate()        {            while (socket != null)            {                try                {                    int count = socket.Receive(buffData);                    if (count <= 0)                    {                        Thread.Sleep(1);                        return;                    }                    // LogTool.Log("数据来了" + count);                    try                    {                        int currCount = 0;                        int startIndex = 0;                        // bool isEnd = false;                        while (currCount < count)                        {                            // isEnd = true;                            byte[] data = null;                            byte sendType = 0;                            int cdShort = 0;                            if (!isBufferData)                            {                                if (weiBaoBuffData != null)                                {                                    int maxCount = 6553500;                                    if (count + weiBaoBuffData.Length > maxCount)                                    {                                        maxCount = count + weiBaoBuffData.Length;                                    }                                    // LogTool.Log("修复包太短__" + count + "___" + weiBaoBuffData.Length);                                    byte[] newBuff = new byte[maxCount];                                    Array.Copy(weiBaoBuffData, 0, newBuff, 0, weiBaoBuffData.Length);                                    Array.Copy(buffData, 0, newBuff, weiBaoBuffData.Length, count);                                    buffData = newBuff;                                    count += weiBaoBuffData.Length;                                    // LogTool.Log("修复包后太短__" + count);                                    if (count < 6)                                    {                                        weiBaoBuffData = new byte[count];                                        // LogTool.Log("包太短222__" + count);                                        Array.Copy(buffData, currCount, weiBaoBuffData, 0, count);                                        break;                                    }                                    else                                    {                                        weiBaoBuffData = null;                                    }                                }                                else                                {                                    if (count - currCount < 5)                                    {                                        weiBaoBuffData = new byte[count];                                        // LogTool.Log("包太短__" + count);                                        Array.Copy(buffData, currCount, weiBaoBuffData, 0, count);                                        break;                                    }                                }                            }                            if (!isBufferData)                            {                                sendType = buffData[currCount];                                currCount++;                                byte[] dataBuffLanl = new byte[4];                                dataBuffLanl[0] = buffData[currCount];                                currCount++;                                dataBuffLanl[1] = buffData[currCount];                                currCount++;                                dataBuffLanl[2] = buffData[currCount];                                currCount++;                                dataBuffLanl[3] = buffData[currCount];                                currCount++;                                cdShort = (SocketTool.ByteToInt(dataBuffLanl));                                // LogTool.Log("数据到来" + cdShort + "__" + count + "_" + sendType);                                if ((currCount + cdShort) > count) //处理半包情况                                {                                    lastBuffData = new byte[count - currCount];                                    lastCount = cdShort;                                    lastSendType = sendType;                                    Array.Copy(buffData, currCount, lastBuffData, 0, lastBuffData.Length);                                    // LogTool.Log("数据只有一半" + count + "__" + currCount + "___" + cdShort);                                    isBufferData = true;                                    break;                                }                                else                                {                                    // LogTool.Log(currCount + "_收到长度:" + cdShort + "_Max" + count);                                    data = new byte[cdShort];                                    Array.Copy(buffData, currCount, data, 0, data.Length);                                }                            }                            else if (lastCount - lastBuffData.Length > count)                            {                                // LogTool.Log("数据只有一半的一半" + count + "__" + lastCount + "___" + lastBuffData.Length);                                byte[] newLastBuffData = new byte[lastBuffData.Length + count];                                Array.Copy(lastBuffData, 0, newLastBuffData, 0, lastBuffData.Length);                                Array.Copy(buffData, 0, newLastBuffData, lastBuffData.Length, count);                                lastBuffData = newLastBuffData;                                break;                            }                            else if (lastBuffData != null) //处理半包情况                            {                                isBufferData = false;                                // LogTool.Log("修复半包" + lastCount + "__" + count + "___" +                                //             (lastCount - lastBuffData.Length));                                sendType = lastSendType;                                data = new byte[lastCount];                                cdShort = lastCount - lastBuffData.Length;                                Array.Copy(lastBuffData, 0, data, 0, lastBuffData.Length);                                Array.Copy(buffData, currCount, data, lastBuffData.Length, cdShort);                            }                            SendDataType sendDataType = (SendDataType)sendType;                            if (sendDataType == SendDataType.Data)                            {                                using (MemoryStream compressedStream = new MemoryStream(data))                                {                                    using (MemoryStream decompressedStream = new MemoryStream())                                    {                                        using (GZipStream gzipStream =                                               new GZipStream(compressedStream, CompressionMode.Decompress))                                        {                                            gzipStream.CopyTo(decompressedStream);                                        }                                        data = decompressedStream.ToArray();                                    }                                }                            }                            switch (sendDataType)                            {                                case SendDataType.ShakeHands:                                    IsConnection = true;                                    isAwaitReConnect = false;                                    _cTask.SetResult();                                    LogTool.Log("握手成功");                                    break;                                case SendDataType.Data:                                    // CombatSynchronizeResponsePack combatSynchronizeResponse =                                    //     CombatSynchronizeResponsePack.Parser.ParseFrom(data);                                    // if (combatSynchronizeResponse == null)                                    // {                                    //     LogTool.Error("错误的实例化战斗" + data.Length);                                    // }                                    // else                                    // {                                    //     IsConnection = true;                                    //     isAwaitReConnect = false;                                    //     long t = System.DateTime.Now.Ticks;                                    //     // LogTool.Log("收包延迟" + (t - combatSynchronizeResponse.Time) / 10000);                                    //     // LogTool.Error("收到客户端消息" + combatSynchronizeRequest.CombatSynchronizeType);                                    //     client.AddCombatSynchronizeResponse(combatSynchronizeResponse);                                    // }                                    break;                            }                            currCount += cdShort;                            startIndex = currCount;                        }                    }                    catch (Exception e)                    {                        LogTool.Exception(e);                        // LogTool.Log("");                    }                }                catch (Exception e)                {                    // LogTool.Log(e);                    break;                }                Thread.Sleep(1);            }            IsConnection = false;            disconnect = true;            LogTool.Log("服务器执行完毕");        }        public void SendToServer(SendDataType sendDataType, byte[] buffer)        {            byte[] mdata = null;            // LogTool.Log("回复消息" + buffer.Length);            mdata = new byte[buffer.Length + 5];            mdata[0] = (byte)sendDataType;            byte[] zcd = SocketTool.IntToByte(buffer.Length);            mdata[1] = zcd[0];            mdata[2] = zcd[1];            mdata[3] = zcd[2];            mdata[4] = zcd[3];            Array.Copy(buffer, 0, mdata, 5, buffer.Length);            try            {                socket.Send(mdata);            }            catch (Exception e)            {                LogTool.Exception(e);            }        }        public void Finish()        {            isFinish = true;        }        public void Dispose()        {            socket?.Close();            socket?.Dispose();            socket = null;            _udpClientThread = null;        }    }}
 |