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
}