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;
- }
- }
- }
|