NewN_UAVPlane/Assets/Zion/Scripts/Socket/ClientSocket.cs

538 lines
17 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
/// <summary>
/// 客户端socket是属于那一种处理方式
/// </summary>
public enum OpenClientSocketEnum
{
Null,
,
}
public class ClientSocket
{
#region
public Socket socket;
public byte[] readBuff;
List<byte> cache = new List<byte>();
public List<string> reciveMessagejosn = new List<string>();//收到的消息列表
public List<byte[]> sendMessages = new List<byte[]>();//发送列表
private bool isreading = false;
public bool threadRun = true;//线程运行控制
public Action<bool, int> closeExeCallBack = null;//关闭exe回调
public Action<bool, string> 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);
}
/// <summary>
///接收数据(线程)
/// </summary>
public void BeginRecv()
{
UnityEngine.Debug.Log("开始接收消息");
socket.BeginReceive(readBuff, 0, 1024, SocketFlags.None, ReciveCallBack, readBuff);//开始接收客户端发送字节
}
/// <summary>
/// 接收回调委托
/// </summary>
/// <param name="ar"></param>
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();
}
}
}
}
/// <summary>
/// 解析消息
/// </summary>
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();//递归,直到全部解析完成
}
/// <summary>
///消息体长度解码(去头部)
/// </summary>
/// <returns></returns>
public byte[] Decode(ref List<byte> 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;
}
/// <summary>
/// 消息体内容解析(json字符串)
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public string Mdecode(byte[] value)
{
string jsonStr = Encoding.UTF8.GetString(value);//反序列化为jstring
return jsonStr;
}
/// <summary>
/// 加入发送队列(改成直接发送消息)
/// </summary>
/// <param name="tmpStr"></param>
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();
}
}
}
}
/// <summary>
/// 处理消息
/// </summary>
public void MessageRecive(string json)
{
try
{
if (json == null || json == "")
{
return;
}
MessageModel message = LitJson.JsonMapper.ToObject<MessageModel>(json);
switch (message.operationEnum)
{
case SimOperationEnum.:
//步骤
if (zhiHuiCallBack != null)
{
zhiHuiCallBack(true, message.str);
zhiHuiCallBack = null;
}
else
{
// HandleResult._Instance.zhiHuiStr.AddRange(JsonConvert.DeserializeObject<List<string>>(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连接仿真服务器
/// <summary>
/// 连接仿真服务器
/// </summary>
public static void ConnectFangZhenSocekt(string serverIP, int port,Action<bool> 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);
}
}
}
}
/// <summary>
/// 关闭仿真服务器客户端
/// </summary>
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("连接仿真服务器失败,请重试");
}
}
}
/// <summary>
/// 发送同步数据给仿真服务器
/// </summary>
/// <param name="message">发送的消息</param>
/// <param name="callback">返回的字符串</param>
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("连接仿真服务器失败,请重试");
}
}
}
/// <summary>
/// 发送命令给仿真服务器
/// </summary>
/// <param name="message"></param>
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("连接仿真服务器失败,请重试");
}
}
}
/// <summary>
/// 发送指挥给仿真服务器
/// </summary>
/// <param name="message">发送的消息</param>
/// <param name="callback">返回的字符串</param>
public static void SendZhiHuiToFangZhenServer(MessageModel message, Action<bool, string> callback)
{
if (fangzhenClient != null && fangzhenClient.socket.Connected)
{
fangzhenClient.zhiHuiCallBack = callback;
fangzhenClient.ReadySend(message);
}
}
/// <summary>
/// 同步设备字典
/// </summary>
/// <param name="deviceId"></param>
/// <param name="content"></param>
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
}