using System; using System.IO; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Threading.Channels; using System.Linq; using System.Net.Http; using System.Collections.Generic; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System.Net; using System.Net.Sockets; using System.Diagnostics; using ProtoDataBuff; using BossServer; using pb = global::Google.Protobuf; namespace clientTest.bossfight { class Program { static readonly Random r = new Random(); /// /// 消息分发 /// static private Dictionary> callbacks = new Dictionary>(); static void Main(string[] args) { callbacks.Add(eProtocalCommand.ScUpdateProperties, On_update); callbacks.Add(eProtocalCommand.ScGameOver, On_GameOver); var n = 1; var list = new Task[n]; for (int i = 0; i < n; i++) { list[i] = Task.Run(async () => await send()); } Task.Run(Dispatch); Task.WaitAll(list); } /// /// 处理客户端上报伤害请求 /// static void On_update(sSocketData data) { var msg = SCUpdateProperties.Parser.ParseFrom(data._data); Console.WriteLine("最新HP: " + msg.BossHp); } /// /// 处理客户端上报伤害请求 /// static void On_GameOver(sSocketData data) { var msg = SCGameOver.Parser.ParseFrom(data._data); Console.WriteLine("战斗结束: " + msg.BossHp); Task.Delay(3000).ContinueWith(t => Environment.Exit(0)); } static async Task send() { var port = 6002; var endPoint = new IPEndPoint(IPAddress.Parse("192.168.10.86"), port); //var endPoint = new IPEndPoint(IPAddress.Parse("115.159.121.129"), port); using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) { try { await client.ConnectAsync(endPoint); } catch (Exception ee) { Debug.WriteLine(ee.Message); } var t = Task.Run(() => recv(client)); await login(client); while (true) { try { await ReportDamage(client); Thread.Sleep(r.Next(1000, 3000)); } catch (Exception e) { client.Close(); break; } } } } async static Task login(Socket Sock) { try { var msg = new CSEnterFight() { Uid = Guid.NewGuid().ToString(), Zoneid = 1 }; var data = SocketDataToBytes(BytesToSocketData(eProtocalCommand.CsLogin, IMsg2Bytes(msg))); await Sock.SendAsync(new ArraySegment(data), SocketFlags.None); } catch (Exception e) { Sock.Close(); } } async static Task ReportDamage(Socket sock) { var msg = new CSFightReportDamage() { Damage = r.Next(-320, 0) }; var data = SocketDataToBytes(BytesToSocketData(eProtocalCommand.CsReportDamage, IMsg2Bytes(msg))); await sock.SendAsync(new ArraySegment(data), SocketFlags.None); } static byte[] IMsg2Bytes(pb::IMessage msg) { using var ms = new MemoryStream(); using var goutstream = new pb::CodedOutputStream(ms); msg.WriteTo(goutstream); goutstream.Flush(); ms.Seek(0, SeekOrigin.Begin); return ms.ToArray(); } static async void Dispatch() { while (true) { var msg = await recvDataBuffer.Reader.ReadAsync(); if (callbacks.ContainsKey(msg._protocallType)) { callbacks[msg._protocallType](msg); } else { // 未找到消息处理逻辑 Console.WriteLine("未识别的消息类型:" + msg._protocallType.ToString()); } } } /// /// 向客户端写入消息 /// static async void WriteToserver(Socket Sock) { while (true) { var msg = await sendDataBuffer.Reader.ReadAsync(); var data = SocketDataToBytes(msg); await Sock.SendAsync(new ArraySegment(data), SocketFlags.None); } } /// /// 网络结构转数据 /// /// /// static private byte[] SocketDataToBytes(sSocketData tmpSocketData) { byte[] _tmpBuff = new byte[tmpSocketData.PackLen]; byte[] _tmpBuffLength = BitConverter.GetBytes(tmpSocketData.PackLen); byte[] _tmpDataLenght = BitConverter.GetBytes((UInt16)tmpSocketData._protocallType); Array.Copy(_tmpBuffLength, 0, _tmpBuff, 0, Constants.HEAD_DATA_LEN);//缓存总长度 Array.Copy(_tmpDataLenght, 0, _tmpBuff, Constants.HEAD_DATA_LEN, Constants.HEAD_TYPE_LEN);//协议类型 Array.Copy(tmpSocketData._data, 0, _tmpBuff, Constants.HEAD_LEN, tmpSocketData.DataLen);//协议数据 return _tmpBuff; } /// /// 数据转网络结构 /// /// /// /// static private sSocketData BytesToSocketData(eProtocalCommand _protocalType, byte[] _data) { sSocketData tmpSocketData = new sSocketData(); tmpSocketData.PackLen = Constants.HEAD_LEN + _data.Length; // tmpSocketData._dataLength = _data.Length; tmpSocketData._protocallType = _protocalType; tmpSocketData._data = _data; return tmpSocketData; } /// /// 接收buffer /// static private Channel recvDataBuffer = Channel.CreateUnbounded(); /// /// 发送buffer /// static private Channel sendDataBuffer = Channel.CreateUnbounded(); /// /// 接收客户端发来的信息,客户端套接字对象 /// /// static async void recv(Socket socketServer) { socketServer.ReceiveTimeout = 800; // 接收等待超时时间设为800毫秒 var _databuffer = new DataBuffer(); byte[] arrServerRecMsg = new byte[4096]; // 创建一个内存缓冲区,其大小为4k字节 while (true) { try { var length = await socketServer.ReceiveAsync(new ArraySegment(arrServerRecMsg), SocketFlags.None); // 将接收到的信息存入到内存缓冲区,并返回其字节数组的长度 if (length <= 0) // 视为客户端已经close连接 { break; } _databuffer.AddBuffer(arrServerRecMsg, length); //将收到的数据添加到缓存器中 while (_databuffer.GetData(out sSocketData _socketData)) //取出一条完整数据 { await recvDataBuffer.Writer.WriteAsync(_socketData); // 放入channel } Array.Clear(arrServerRecMsg, 0, length); } catch (SocketException e) { if (e.ErrorCode == 10060) // 超时的时候错误号码是10060 { continue; // 继续等待 } break; } catch (Exception) { break; } } socketServer.Close(); // 关闭之前accept出来的和客户端进行通信的套接字 } } }