Program.cs 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. using System;
  2. using System.IO;
  3. using System.Text;
  4. using System.Threading;
  5. using System.Threading.Tasks;
  6. using System.Threading.Channels;
  7. using System.Linq;
  8. using System.Net.Http;
  9. using System.Collections.Generic;
  10. using Newtonsoft.Json;
  11. using Newtonsoft.Json.Linq;
  12. using System.Net;
  13. using System.Net.Sockets;
  14. using System.Diagnostics;
  15. using ProtoDataBuff;
  16. using BossServer;
  17. using pb = global::Google.Protobuf;
  18. namespace clientTest.bossfight
  19. {
  20. class Program
  21. {
  22. static readonly Random r = new Random();
  23. /// <summary>
  24. /// 消息分发
  25. /// </summary>
  26. static private Dictionary<eProtocalCommand, Action<sSocketData>> callbacks = new Dictionary<eProtocalCommand, Action<sSocketData>>();
  27. static void Main(string[] args)
  28. {
  29. callbacks.Add(eProtocalCommand.ScUpdateProperties, On_update);
  30. callbacks.Add(eProtocalCommand.ScGameOver, On_GameOver);
  31. var n = 1;
  32. var list = new Task[n];
  33. for (int i = 0; i < n; i++)
  34. {
  35. list[i] = Task.Run(async () => await send());
  36. }
  37. Task.Run(Dispatch);
  38. Task.WaitAll(list);
  39. }
  40. /// <summary>
  41. /// 处理客户端上报伤害请求
  42. /// </summary>
  43. static void On_update(sSocketData data)
  44. {
  45. var msg = SCUpdateProperties.Parser.ParseFrom(data._data);
  46. Console.WriteLine("最新HP: " + msg.BossHp);
  47. }
  48. /// <summary>
  49. /// 处理客户端上报伤害请求
  50. /// </summary>
  51. static void On_GameOver(sSocketData data)
  52. {
  53. var msg = SCGameOver.Parser.ParseFrom(data._data);
  54. Console.WriteLine("战斗结束: " + msg.BossHp);
  55. Task.Delay(3000).ContinueWith(t => Environment.Exit(0));
  56. }
  57. static async Task send()
  58. {
  59. var port = 6002;
  60. var endPoint = new IPEndPoint(IPAddress.Parse("192.168.10.86"), port);
  61. //var endPoint = new IPEndPoint(IPAddress.Parse("115.159.121.129"), port);
  62. using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
  63. {
  64. try
  65. {
  66. await client.ConnectAsync(endPoint);
  67. }
  68. catch (Exception ee)
  69. {
  70. Debug.WriteLine(ee.Message);
  71. }
  72. var t = Task.Run(() => recv(client));
  73. await login(client);
  74. while (true)
  75. {
  76. try
  77. {
  78. await ReportDamage(client);
  79. Thread.Sleep(r.Next(1000, 3000));
  80. }
  81. catch (Exception e)
  82. {
  83. client.Close();
  84. break;
  85. }
  86. }
  87. }
  88. }
  89. async static Task login(Socket Sock)
  90. {
  91. try
  92. {
  93. var msg = new CSEnterFight() { Uid = Guid.NewGuid().ToString(), Zoneid = 1 };
  94. var data = SocketDataToBytes(BytesToSocketData(eProtocalCommand.CsLogin, IMsg2Bytes(msg)));
  95. await Sock.SendAsync(new ArraySegment<byte>(data), SocketFlags.None);
  96. }
  97. catch (Exception e)
  98. {
  99. Sock.Close();
  100. }
  101. }
  102. async static Task ReportDamage(Socket sock)
  103. {
  104. var msg = new CSFightReportDamage() { Damage = r.Next(-320, 0) };
  105. var data = SocketDataToBytes(BytesToSocketData(eProtocalCommand.CsReportDamage, IMsg2Bytes(msg)));
  106. await sock.SendAsync(new ArraySegment<byte>(data), SocketFlags.None);
  107. }
  108. static byte[] IMsg2Bytes(pb::IMessage msg)
  109. {
  110. using var ms = new MemoryStream();
  111. using var goutstream = new pb::CodedOutputStream(ms);
  112. msg.WriteTo(goutstream);
  113. goutstream.Flush();
  114. ms.Seek(0, SeekOrigin.Begin);
  115. return ms.ToArray();
  116. }
  117. static async void Dispatch()
  118. {
  119. while (true)
  120. {
  121. var msg = await recvDataBuffer.Reader.ReadAsync();
  122. if (callbacks.ContainsKey(msg._protocallType))
  123. {
  124. callbacks[msg._protocallType](msg);
  125. }
  126. else
  127. {
  128. // 未找到消息处理逻辑
  129. Console.WriteLine("未识别的消息类型:" + msg._protocallType.ToString());
  130. }
  131. }
  132. }
  133. /// <summary>
  134. /// 向客户端写入消息
  135. /// </summary>
  136. static async void WriteToserver(Socket Sock)
  137. {
  138. while (true)
  139. {
  140. var msg = await sendDataBuffer.Reader.ReadAsync();
  141. var data = SocketDataToBytes(msg);
  142. await Sock.SendAsync(new ArraySegment<byte>(data), SocketFlags.None);
  143. }
  144. }
  145. /// <summary>
  146. /// 网络结构转数据
  147. /// </summary>
  148. /// <param name="tmpSocketData"></param>
  149. /// <returns></returns>
  150. static private byte[] SocketDataToBytes(sSocketData tmpSocketData)
  151. {
  152. byte[] _tmpBuff = new byte[tmpSocketData._buffLength];
  153. byte[] _tmpBuffLength = BitConverter.GetBytes(tmpSocketData._buffLength);
  154. byte[] _tmpDataLenght = BitConverter.GetBytes((UInt16)tmpSocketData._protocallType);
  155. Array.Copy(_tmpBuffLength, 0, _tmpBuff, 0, Constants.HEAD_DATA_LEN);//缓存总长度
  156. Array.Copy(_tmpDataLenght, 0, _tmpBuff, Constants.HEAD_DATA_LEN, Constants.HEAD_TYPE_LEN);//协议类型
  157. Array.Copy(tmpSocketData._data, 0, _tmpBuff, Constants.HEAD_LEN, tmpSocketData._dataLength);//协议数据
  158. return _tmpBuff;
  159. }
  160. /// <summary>
  161. /// 数据转网络结构
  162. /// </summary>
  163. /// <param name="_protocalType"></param>
  164. /// <param name="_data"></param>
  165. /// <returns></returns>
  166. static private sSocketData BytesToSocketData(eProtocalCommand _protocalType, byte[] _data)
  167. {
  168. sSocketData tmpSocketData = new sSocketData();
  169. tmpSocketData._buffLength = Constants.HEAD_LEN + _data.Length;
  170. tmpSocketData._dataLength = _data.Length;
  171. tmpSocketData._protocallType = _protocalType;
  172. tmpSocketData._data = _data;
  173. return tmpSocketData;
  174. }
  175. /// <summary>
  176. /// 接收buffer
  177. /// </summary>
  178. static private Channel<sSocketData> recvDataBuffer = Channel.CreateUnbounded<sSocketData>();
  179. /// <summary>
  180. /// 发送buffer
  181. /// </summary>
  182. static private Channel<sSocketData> sendDataBuffer = Channel.CreateUnbounded<sSocketData>();
  183. /// <summary>
  184. /// 接收客户端发来的信息,客户端套接字对象
  185. /// </summary>
  186. /// <param name="socketclientpara"></param>
  187. static async void recv(Socket socketServer)
  188. {
  189. socketServer.ReceiveTimeout = 800; // 接收等待超时时间设为800毫秒
  190. var _databuffer = new DataBuffer();
  191. byte[] arrServerRecMsg = new byte[4096]; // 创建一个内存缓冲区,其大小为4k字节
  192. while (true)
  193. {
  194. try
  195. {
  196. var length = await socketServer.ReceiveAsync(new ArraySegment<byte>(arrServerRecMsg), SocketFlags.None); // 将接收到的信息存入到内存缓冲区,并返回其字节数组的长度
  197. if (length <= 0) // 视为客户端已经close连接
  198. {
  199. break;
  200. }
  201. _databuffer.AddBuffer(arrServerRecMsg, length); //将收到的数据添加到缓存器中
  202. while (_databuffer.GetData(out sSocketData _socketData)) //取出一条完整数据
  203. {
  204. await recvDataBuffer.Writer.WriteAsync(_socketData); // 放入channel
  205. }
  206. Array.Clear(arrServerRecMsg, 0, length);
  207. }
  208. catch (SocketException e)
  209. {
  210. if (e.ErrorCode == 10060) // 超时的时候错误号码是10060
  211. {
  212. continue; // 继续等待
  213. }
  214. break;
  215. }
  216. catch (Exception)
  217. {
  218. break;
  219. }
  220. }
  221. socketServer.Close(); // 关闭之前accept出来的和客户端进行通信的套接字
  222. }
  223. }
  224. }