using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using UnityEngine; /// /// 客户端socket是属于那一种处理方式 /// public enum OpenClientSocketEnum { Null, 客户端, 服务端 } public class ClientSocket { #region 网络模块 public Socket socket; public byte[] readBuff; List cache = new List(); public List reciveMessagejosn = new List();//收到的消息列表 public List sendMessages = new List();//发送列表 private bool isreading = false; public bool threadRun = true;//线程运行控制 public Action closeExeCallBack = null;//关闭exe回调 public Action zhiHuiCallBack = null;//指挥回调 // public Timer timer; public byte[] currentMessage; public OpenClientSocketEnum openClientSocketEnum;//打开类型 public bool success = true;//是否成功发送消息 public ClientSocket(Socket tmpsocket, OpenClientSocketEnum openClientSocketEnum) { readBuff = new byte[1024]; socket = tmpsocket; socket.ReceiveTimeout = 8000; socket.SendTimeout = 8000; this.openClientSocketEnum = openClientSocketEnum; // timer = new Timer(TimerCallBack, currentMessage, Timeout.Infinite, 10000); } /// ///接收数据(线程) /// public void BeginRecv() { UnityEngine.Debug.Log("开始接收消息"); socket.BeginReceive(readBuff, 0, 1024, SocketFlags.None, ReciveCallBack, readBuff);//开始接收客户端发送字节 } /// /// 接收回调委托 /// /// public void ReciveCallBack(IAsyncResult ar) { try { int length = socket.EndReceive(ar);//接收完成 byte[] massge = new byte[length]; //接受0字节关闭socket if(length==0) { if(openClientSocketEnum == OpenClientSocketEnum.客户端) { threadRun = false; if(socket.Connected) { socket.Shutdown(SocketShutdown.Both); } socket.Close(); // ServerSocket.socketList.Remove(this); } } Buffer.BlockCopy(readBuff, 0, massge, 0, length);//拷贝消息 cache.AddRange(massge);//存储消息 if (isreading == false) { isreading = true; OnDate();//解析数据 } else { Console.WriteLine("数据正在被读"); } if (threadRun == true) { //递归 if (socket == null) { threadRun = false; } else { if (!socket.Connected) { threadRun = false; socket.Close(); } } if (socket != null) { socket.BeginReceive(readBuff, 0, 1024, SocketFlags.None, ReciveCallBack, readBuff);//接收下一条消息 } } //else //{ // return; //} } catch(Exception e) { UnityEngine.Debug.Log("接受线程异常"+e.Message); if (openClientSocketEnum == OpenClientSocketEnum.客户端) { if (fangzhenClient != null && this == fangzhenClient) { if (!fangzhenClient.socket.Connected) { //断线重连 ConnectFangZhenSocekt(LoadManage.Instance.currentPractice.IpAddress, LoadManage.Instance.currentPractice.Port.Value); } //CloseFangZhenSocket(); } } } } /// /// 解析消息 /// public void OnDate() { //反序列化 byte[] result = Decode(ref cache); //如果解析完了,重新置为可读 if (result == null) { isreading = false; return; } //消息体解码 string message = Mdecode(result); if (message == null) { Console.WriteLine("message为空"); isreading = false; return; } //存储消息体(json) //reciveMessagejosn.Add(message); //处理消息 if (openClientSocketEnum == OpenClientSocketEnum.客户端) { MessageRecive(message); } OnDate();//递归,直到全部解析完成 } /// ///消息体长度解码(去头部) /// /// public byte[] Decode(ref List cache) { if (cache.Count < 4) { return null; } MemoryStream ms = new MemoryStream(cache.ToArray());//内存流读写消息 BinaryReader br = new BinaryReader(ms);//二进制读取 int length = br.ReadInt32();//读取头部4个字节,得到消息内容长度 if (length > ms.Length - ms.Position)//消息不完整 { //UnityEngine.Debug.Log("消息不完整"); return null; } byte[] result = br.ReadBytes(length);//光标继续移动,读取消息内容 cache.Clear();//清空消息 cache.AddRange(br.ReadBytes((int)(ms.Length - ms.Position)));//去掉第一个消息 br.Close(); ms.Close(); return result; } /// /// 消息体内容解析(json字符串) /// /// /// public string Mdecode(byte[] value) { string jsonStr = Encoding.UTF8.GetString(value);//反序列化为jstring return jsonStr; } /// /// 加入发送队列(改成直接发送消息) /// /// public void ReadySend(MessageModel message) { try { if(!this.socket.Connected) { UnityEngine.Debug.Log("未连接,发送失败"); return; } if (message == null) { return; } //实例化一个消息对象 string jsonstr = LitJson.JsonMapper.ToJson(message); byte[] ba = Encoding.UTF8.GetBytes(jsonstr);//得到byte[] message if (ba.Length == 0) { return; } //长度编码 ByteArray arr = new ByteArray(); arr.Write(ba.Length); arr.Write(ba); byte[] sendBuffer = arr.GetBuffer(); socket.Send(sendBuffer); } catch(Exception e) { UnityEngine.Debug.Log("发送错误"+e.Message); if (openClientSocketEnum == OpenClientSocketEnum.客户端) { if (fangzhenClient != null && this == fangzhenClient) { if(!fangzhenClient.socket.Connected) { //断线重连 ConnectFangZhenSocekt(LoadManage.Instance.currentPractice.IpAddress, LoadManage.Instance.currentPractice.Port.Value); } //CloseFangZhenSocket(); } } } } /// /// 处理消息 /// public void MessageRecive(string json) { try { if (json == null || json == "") { return; } MessageModel message = LitJson.JsonMapper.ToObject(json); switch (message.operationEnum) { case SimOperationEnum.指挥指令服务端: //步骤 if (zhiHuiCallBack != null) { zhiHuiCallBack(true, message.str); zhiHuiCallBack = null; } else { // HandleResult._Instance.zhiHuiStr.AddRange(JsonConvert.DeserializeObject>(message.str)); } break; case SimOperationEnum.科目启停服务端: //转发给给服务器 //HandleResult._Instance.subjectSet.Add(message.str); break; case SimOperationEnum.科目切换服务端: //HandleResult._Instance.changeSubject.Add(message); break; case SimOperationEnum.操作软件二维端: //操作软件发来的 //SoftManage.Instance.Soft.Add(message); break; } } catch(Exception e) { UnityEngine.Debug.LogWarning(json); UnityEngine.Debug.LogWarning(e.Message); } } #endregion #region 协同交互调用模块 public static ClientSocket fangzhenClient;//客户端socket连接仿真服务器 /// /// 连接仿真服务器 /// public static void ConnectFangZhenSocekt(string serverIP, int port,Action action=null) { UnityEngine.Debug.Log("开启仿真服务器客户端socket:"+ serverIP+ ":port"); if (fangzhenClient!=null && fangzhenClient.socket.Connected) { UnityEngine.Debug.Log("仿真客户端不为空"); if (action != null) { action(true); } } else { try { UnityEngine.Debug.Log("正在连接仿真服务器中。。。。"); Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket.Connect(IPAddress.Parse(serverIP), port); if (socket.Connected) { UnityEngine.Debug.Log("连接成功"); //创建客户端对象 fangzhenClient = new ClientSocket(socket, OpenClientSocketEnum.客户端); //开启异步接收 fangzhenClient.BeginRecv(); if (action != null) { action(true); } } else { if (action != null) { action(false); } else { UnityEngine.Debug.Log("连接仿真服务器失败,重新连接"); ConnectFangZhenSocekt(serverIP, port); } } } catch(Exception e) { UnityEngine.Debug.Log("连接仿真服务器失败,请重试:"+e.Message); if (action != null) { action(false); } } } } /// /// 关闭仿真服务器客户端 /// public static void CloseFangZhenSocket() { if (fangzhenClient != null) { fangzhenClient.threadRun = false; if (fangzhenClient.socket.Connected) { fangzhenClient.socket.Shutdown(SocketShutdown.Both); } fangzhenClient.socket.Close(); fangzhenClient = null; UnityEngine.Debug.Log("关闭仿真服务客户端socket成功"); } } public static void SendToTongBuFangZhenServerByAllUser(MessageModel message) { if (fangzhenClient != null) { if (fangzhenClient.socket.Connected) { fangzhenClient.ReadySend(message); } else { ConnectFangZhenSocekt(LoadManage.Instance.currentPractice.IpAddress, LoadManage.Instance.currentPractice.Port.Value, (a) => { if(a) { fangzhenClient.ReadySend(message); } else { UnityEngine.Debug.Log("连接失败"); } }); } } else { try { UnityEngine.Debug.Log("正在连接仿真服务器中。。。。"); Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket.Connect(IPAddress.Parse(LoadManage.Instance.currentPractice.IpAddress), LoadManage.Instance.currentPractice.Port.Value); if (socket.Connected) { UnityEngine.Debug.Log("连接成功"); //创建客户端对象 fangzhenClient = new ClientSocket(socket, OpenClientSocketEnum.客户端); //开启异步接收 fangzhenClient.BeginRecv(); fangzhenClient.ReadySend(message); } } catch { UnityEngine.Debug.Log("连接仿真服务器失败,请重试"); } } } /// /// 发送同步数据给仿真服务器 /// /// 发送的消息 /// 返回的字符串 public static void SendToTongBuFangZhenServer(MessageModel message) { if (fangzhenClient != null && fangzhenClient.socket.Connected) { fangzhenClient.ReadySend(message); //UnityEngine.Debug.Log("发送的同步消息内容:__________ " + message.str); } else { try { UnityEngine.Debug.Log("正在连接仿真服务器中。。。。"); Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket.Connect(IPAddress.Parse(LoadManage.Instance.currentPractice.IpAddress), LoadManage.Instance.currentPractice.Port.Value); if (socket.Connected) { UnityEngine.Debug.Log("连接成功"); //创建客户端对象 fangzhenClient = new ClientSocket(socket, OpenClientSocketEnum.客户端); //开启异步接收 fangzhenClient.BeginRecv(); fangzhenClient.ReadySend(message); //UnityEngine.Debug.Log("发送的同步消息内容:__________ " + message.str); } } catch { UnityEngine.Debug.Log("连接仿真服务器失败,请重试"); } } } /// /// 发送命令给仿真服务器 /// /// public static void SendCommondToFangZhenServer(MessageModel message) { if (fangzhenClient != null && fangzhenClient.socket.Connected) { fangzhenClient.ReadySend(message); } else { try { UnityEngine.Debug.Log("正在连接仿真服务器中。。。。"); Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket.Connect(IPAddress.Parse(LoadManage.Instance.currentPractice.IpAddress), LoadManage.Instance.currentPractice.Port.Value); if (socket.Connected) { UnityEngine.Debug.Log("连接成功"); //创建客户端对象 fangzhenClient = new ClientSocket(socket, OpenClientSocketEnum.客户端); //开启异步接收 fangzhenClient.BeginRecv(); fangzhenClient.ReadySend(message); } } catch { UnityEngine.Debug.Log("连接仿真服务器失败,请重试"); } } } /// /// 发送指挥给仿真服务器 /// /// 发送的消息 /// 返回的字符串 public static void SendZhiHuiToFangZhenServer(MessageModel message, Action callback) { if (fangzhenClient != null && fangzhenClient.socket.Connected) { fangzhenClient.zhiHuiCallBack = callback; fangzhenClient.ReadySend(message); } } /// /// 同步设备字典 /// /// /// public static void DevicesSyncByDic(string deviceId,string content) { MessageModel message = new MessageModel(SimOperationEnum.数据同步客户端); message.str = "设备属性按字典同步字典"; message.canShu = deviceId +"$"+ content; if (fangzhenClient != null && fangzhenClient.socket.Connected) { fangzhenClient.ReadySend(message); } } #endregion }