TCPServer.cs 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. #if COMBAT_SERVER
  2. using System;
  3. using System.Collections.Generic;
  4. using System.IO.Compression;
  5. using System.Net;
  6. using System.Net.Sockets;
  7. using System.Threading;
  8. using Com.Fort23.Protocol.Protobuf;
  9. using Fort23.UTool;
  10. using Utility;
  11. using Task = System.Threading.Tasks.Task;
  12. namespace Core.KCPTool
  13. {
  14. public class TCPServer : IServer
  15. {
  16. private byte[] buffData = new byte[6553];
  17. private Socket socket;
  18. //记录半包数据
  19. private bool isBufferData;
  20. private byte[] lastBuffData;
  21. private int lastCount;
  22. private short lastXueLieHao;
  23. //数据结束
  24. //尾包
  25. private byte[] weiBaoBuffData;
  26. // private Thread _udpClientThread;
  27. private byte[] buffer = new byte[2048];
  28. public Map<long, IServerConnection> KcpServerConnections = new Map<long, IServerConnection>();
  29. private List<CombatSynchronizeRequest> CombatSynchronizeRequests = new List<CombatSynchronizeRequest>();
  30. private List<IServerConnection> awaitConnections = new List<IServerConnection>();
  31. private IServerManager iServerManager;
  32. public TCPServer(int port, IServerManager iServerManager)
  33. {
  34. LogTool.Log("创建TCP链接端口"+port+"__");
  35. this.iServerManager = iServerManager;
  36. socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  37. socket.Bind(new IPEndPoint(IPAddress.Any, port));
  38. socket.Listen();
  39. AcceptAsync();
  40. }
  41. public void AddCombatSynchronizeRequest(CombatSynchronizeRequest combatSynchronizeRequest)
  42. {
  43. lock (CombatSynchronizeRequests)
  44. {
  45. CombatSynchronizeRequests.Add(combatSynchronizeRequest);
  46. }
  47. }
  48. public CombatSynchronizeRequest[] GetCombatSynchronizeRequest(bool isClear)
  49. {
  50. if (CombatSynchronizeRequests.Count <= 0)
  51. {
  52. return null;
  53. }
  54. lock (CombatSynchronizeRequests)
  55. {
  56. CombatSynchronizeRequest[] allData = CombatSynchronizeRequests.ToArray();
  57. CombatSynchronizeRequests.Clear();
  58. return allData;
  59. }
  60. }
  61. private byte[] AssembleData(SendDataType sendDataType, byte[] buffer)
  62. {
  63. byte[] sendBuff = new byte[buffer.Length + 5];
  64. sendBuff[0] = (byte)sendDataType;
  65. byte[] zcd = SocketTool.IntToByte(buffer.Length);
  66. sendBuff[1] = zcd[0];
  67. sendBuff[2] = zcd[1];
  68. sendBuff[3] = zcd[2];
  69. sendBuff[4] = zcd[3];
  70. Array.Copy(buffer, 0, sendBuff, 5, buffer.Length);
  71. return sendBuff;
  72. }
  73. public bool SendToPlayer(SendDataType sendDataType, CombatSynchronizeType combatSynchronizeType, byte[] buffer,
  74. long playerId)
  75. {
  76. if (KcpServerConnections.Count <= 0)
  77. {
  78. return true;
  79. }
  80. long t = System.DateTime.Now.Ticks;
  81. byte[] sendBuff = AssembleData(sendDataType, buffer);
  82. long t2 = System.DateTime.Now.Ticks;
  83. bool isOk = false;
  84. lock (KcpServerConnections)
  85. {
  86. for (KcpServerConnections.Begin(); KcpServerConnections.Next();)
  87. {
  88. if (KcpServerConnections.Value.isConnected)
  89. {
  90. isOk = true;
  91. }
  92. if (playerId != -1 && KcpServerConnections.Value.playerId != playerId)
  93. {
  94. continue;
  95. }
  96. KcpServerConnections.Value.SendData(sendBuff, sendBuff.Length);
  97. }
  98. }
  99. return isOk;
  100. }
  101. public IServerConnection GetConnection(int connectionId)
  102. {
  103. lock (KcpServerConnections)
  104. {
  105. for (KcpServerConnections.Begin(); KcpServerConnections.Next();)
  106. {
  107. if (connectionId != -1 && KcpServerConnections.Value.connectionID != connectionId)
  108. {
  109. continue;
  110. }
  111. return KcpServerConnections.Value;
  112. }
  113. }
  114. return null;
  115. }
  116. public async void SendGameFrame(int gameFrame, IServerConnection kcpServerConnection)
  117. {
  118. // if (gameFrame > 0)
  119. {
  120. LogTool.Log("重传数据开始" + gameFrame);
  121. int maxCount = iServerManager.GetSendBufferSize();
  122. for (int i = gameFrame; i < maxCount; i++)
  123. {
  124. byte[] _sendBufferdata = iServerManager.GetSendBuffer(i);
  125. if (_sendBufferdata != null)
  126. {
  127. _sendBufferdata = AssembleData(SendDataType.Data,_sendBufferdata);
  128. kcpServerConnection.SendData(_sendBufferdata, _sendBufferdata.Length);
  129. await Task.Delay(1);
  130. }
  131. }
  132. }
  133. }
  134. public void AddServerConnection(long playerId, int gameFrame, IServerConnection kcpServerConnection)
  135. {
  136. lock (KcpServerConnections)
  137. {
  138. if (KcpServerConnections.TryGetValue(playerId, out var connection))
  139. {
  140. LogTool.Log("移除成功TCP" + playerId);
  141. connection.Dispose();
  142. KcpServerConnections.Remove(playerId);
  143. }
  144. KcpServerConnections.Add(playerId, kcpServerConnection);
  145. }
  146. lock (awaitConnections)
  147. {
  148. awaitConnections.Remove(kcpServerConnection);
  149. }
  150. LogTool.Log("握手成功TCP" + playerId);
  151. iServerManager.AddServerConnection(this, kcpServerConnection);
  152. byte[] data = SocketTool.LongToByte(playerId);
  153. SendToPlayer(SendDataType.ShakeHands, CombatSynchronizeType.PrepareStart, data, playerId);
  154. }
  155. public void RemoveServerConnection(long playerId)
  156. {
  157. lock (KcpServerConnections)
  158. {
  159. if (KcpServerConnections.TryGetValue(playerId, out IServerConnection serverConnection))
  160. {
  161. LogTool.Log("移除成功TCP" + playerId);
  162. serverConnection.Dispose();
  163. KcpServerConnections.Remove(playerId);
  164. }
  165. }
  166. }
  167. public IServerConnection GetConnection(long playerId)
  168. {
  169. lock (KcpServerConnections)
  170. {
  171. for (KcpServerConnections.Begin(); KcpServerConnections.Next();)
  172. {
  173. if (playerId != -1 && KcpServerConnections.Value.playerId != playerId)
  174. {
  175. continue;
  176. }
  177. return KcpServerConnections.Value;
  178. }
  179. }
  180. return null;
  181. }
  182. public void ConnectionUpdate()
  183. {
  184. }
  185. private async void AcceptAsync()
  186. {
  187. try
  188. {
  189. if (socket == null)
  190. {
  191. return;
  192. }
  193. Socket newSocket = await socket.AcceptAsync();
  194. int code = newSocket.RemoteEndPoint.GetHashCode();
  195. TCPServerConnection tcpServerConnection = new TCPServerConnection(this, newSocket);
  196. tcpServerConnection.connectionID = code;
  197. awaitConnections.Add(tcpServerConnection);
  198. AcceptAsync();
  199. }
  200. catch (Exception e)
  201. {
  202. LogTool.Error(e);
  203. }
  204. }
  205. public void Dispose()
  206. {
  207. socket?.Dispose();
  208. socket = null;
  209. for (KcpServerConnections.Begin(); KcpServerConnections.Next();)
  210. {
  211. KcpServerConnections.Value.Dispose();
  212. }
  213. KcpServerConnections.Clear();
  214. CombatSynchronizeRequests.Clear();
  215. awaitConnections.Clear();
  216. }
  217. }
  218. }
  219. #endif