using System;
|
using System.Collections.Generic;
|
using System.Net.Sockets;
|
using System.Text;
|
using System.Threading;
|
using System.Timers;
|
using HDL_ON;
|
using HDL_ON.Entity;
|
using HDL_ON.UI;
|
|
namespace HDL_ON.DriverLayer
|
{
|
/// <summary>
|
/// link网关本地链接逻辑
|
/// </summary>
|
public class Control_Tcp
|
{
|
#region ■ 变量声明___________________________
|
|
/// <summary>
|
/// link网关链接逻辑
|
/// </summary>
|
private static Control_Tcp m_Current = null;
|
/// <summary>
|
/// link网关链接逻辑
|
/// </summary>
|
public static Control_Tcp Current
|
{
|
get
|
{
|
if (m_Current == null)
|
{
|
m_Current = new Control_Tcp();
|
}
|
return m_Current;
|
}
|
}
|
/// <summary>
|
/// Link网关tcp接收回调,理论上它不会处理zigbee的上报(第一个参数是网关的mac,第二个参数是接收的数据)
|
/// </summary>
|
private Action<string, string, string> tcpReceiveEvent = null;
|
/// <summary>
|
/// Tcp客户端连接池
|
/// </summary>
|
private List<TcpConnectData> listTcpClient = new List<TcpConnectData>();
|
/// <summary>
|
/// 是否搜索网关
|
/// </summary>
|
private bool isSearchGateway = false;
|
|
#endregion
|
|
#region ■ 搜索Link网关_______________________
|
|
// /// <summary>
|
// /// 搜索Link网关
|
// /// </summary>
|
// /// <param name="resultEvent">搜索到网关的回调函数,-1:异常了 1:收到一个A网关</param>
|
// /// <param name="searchTime">搜索时间(秒)</param>
|
// /// <param name="connectLocalOnly">当搜索到网关时,是否只连接本地的(不能瞎连其他的网关,但是网关搜索界面特殊)</param>
|
// public void SearchLinkGateway(Action<int, AGatewayInfo> resultEvent, int searchTime, bool connectLocalOnly)
|
// {
|
// this.isSearchGateway = true;
|
// //算了,在这里启动远程连接吧,反正也就执行一次
|
// HdlLinkCloudConnectLogic.Current.StartCloudMqttConnection();
|
|
// var listGateway = HdlLinkGatewayLogic.Current.GetAllLocalGateway();
|
// var dicGateway = new Dictionary<string, ZigBee.Device.LinkGateway>();
|
// foreach (var gw in listGateway)
|
// {
|
// //获取本地全部的A网关的mac
|
// dicGateway[gw.GwMac] = gw;
|
// }
|
// //重复检测
|
// var listCheck = new HashSet<string>();
|
|
// var sendData = "Topic:/user/all/custom/gateway/search\r\n";
|
|
// var dic = new Dictionary<string, string>();
|
// dic["id"] = HdlGatewayResourse.AGatewayLinkFlage;
|
// dic["time_stamp"] = HdlHttpLogic.Current.GetTimestamp().PadRight(13, '0');
|
// var bodyData = Newtonsoft.Json.JsonConvert.SerializeObject(dic);
|
// sendData += "Length:" + bodyData.Length + "\r\n\r\n";
|
// sendData += bodyData;
|
|
// //初始化udp
|
// var udpLogic = new HdlUdpLogic();
|
// if (udpLogic.InitUdp("239.0.168.188", 8585) == false)
|
// {
|
// //关闭udp
|
// udpLogic.CloseUdp();
|
|
// resultEvent?.Invoke(-1, null);
|
// return;
|
// }
|
|
// HDL_ON.DriverLayer.Control.Ins.OpenUdp(8585);
|
|
// //接收事件
|
// Action<System.Net.IPEndPoint, string> actionEvent = (ipPoint, result) =>
|
// {
|
// //处理搜索A网关时,网关回复的数据
|
// try
|
// {
|
// /////
|
// System.Net.IPAddress s = ipPoint.Address;
|
// MainPage.Log("TcpClient->SearchLinkGateway", $"{s}==网关搜索本地回复,数据内容{result}");
|
|
// //检验A协议网关主题(如果检验是指定主题,则返回负载数据,否则返回null)
|
// var resultData = HdlLinkGatewaySendLogic.Current.CheckLinkGatewayTopic("/user/all/custom/gateway/search_reply", result);
|
// if (resultData == null) { return; }
|
// //调用回调函数
|
// var info = Newtonsoft.Json.JsonConvert.DeserializeObject<AGatewayInfo>(resultData);
|
// if (info == null)
|
// {
|
// //数据异常,退出
|
// return;
|
// }
|
// if (!(string.IsNullOrEmpty(info.HomeId) == true || info.HomeId == Common.Config.Instance.HomeId))
|
// {
|
// //网关已经绑定其他住宅,退出
|
// return;
|
// }
|
// ///tcp连接目标设备的ip
|
// info.Ip_address = ipPoint.Address.ToString();
|
// //搜索到的这个网关,是否是存在在本地了的
|
// if (dicGateway.ContainsKey(info.Device_mac) == true)
|
// {
|
// var gateWay = dicGateway[info.Device_mac];
|
// //如果搜索得到本地存在的网关,则使用本地通信
|
// gateWay.OnlineStatu = 1;
|
// gateWay.isLocalEncrypt = info.isLocalEncrypt;
|
// gateWay.Master = info.Master;
|
// //gateWay.Slaver_list1 = info.Slaver_list1;
|
// gateWay.Oid = info.Oid;
|
// gateWay.InGatewayHomeId = info.HomeId;
|
// info.IsBindGateway = true;
|
|
// Common.Config.Instance.Home.NowHomeOnlineStatu = "1";
|
// }
|
// //搜索到的网关,建立链接
|
// if (connectLocalOnly == false || info.IsBindGateway == true)
|
// {
|
// this.ConnectLocalLinkGateway(info.Device_mac, info.Ip_address, info.GatewayId, info.isLocalEncrypt);
|
// }
|
// else
|
// {
|
// //获取连接对象
|
// var connectObj = this.GetConnectObject(info.Device_mac, false);
|
// if (connectObj != null)
|
// {
|
// //如果有这个对象, 则替换一下它的网关id
|
// connectObj.GatewayId = info.GatewayId;
|
// connectObj.localEncrypt = info.isLocalEncrypt;
|
// return;
|
// }
|
// }
|
// if (listCheck.Contains(info.Device_mac) == true)
|
// {
|
// //已经处理过了
|
// return;
|
// }
|
// listCheck.Add(info.Device_mac);
|
|
|
//#if DEBUG
|
// Console.WriteLine($"搜索网关捕抓到网关:{info.Device_mac}");
|
//#endif
|
// //info
|
|
// //回调函数
|
// resultEvent?.Invoke(1, info);
|
// }
|
// catch (Exception e)
|
// {
|
// string str = e.Message;
|
// }
|
// };
|
// udpLogic.ReceviceEvent += actionEvent;
|
// var dateTime = System.DateTime.Now.AddSeconds(searchTime);
|
// while (this.isSearchGateway && System.DateTime.Now < dateTime)
|
// {
|
// udpLogic.SendData(sendData, "239.0.168.188", 8585);
|
// udpLogic.SendData(sendData, "255.255.255.255", 8585);
|
// System.Threading.Thread.Sleep(1000);
|
// }
|
// udpLogic.ReceviceEvent -= actionEvent;
|
// //别关那么快
|
// System.Threading.Thread.Sleep(300);
|
// this.isSearchGateway = false;
|
// //关闭udp
|
// udpLogic.CloseUdp();
|
|
// }
|
|
// /// <summary>
|
// /// 停止搜索Link网关
|
// /// </summary>
|
// public void StopSearchLinkGateway()
|
// {
|
// this.isSearchGateway = false;
|
// }
|
|
#endregion
|
|
#region ■ 链接本地Link网关___________________
|
|
/// <summary>
|
/// 链接Link网关
|
/// </summary>
|
/// <param name="i_mac">网关mac</param>
|
/// <param name="i_ipAdrr">网关ip</param>
|
/// <param name="i_gwId">网关Id</param>
|
/// <param name="isBinded">该tcp所指向的网关,是否是当前住宅所绑定的</param>
|
/// <returns></returns>
|
public void ConnectLocalLinkGateway(string i_mac, string i_ipAdrr, string i_gwId, bool localEncrypt)
|
{
|
if (i_mac == string.Empty || i_ipAdrr == string.Empty)
|
{
|
return;
|
}
|
var connectData = new TcpConnectData();
|
connectData.GatewayId = i_gwId;
|
connectData.GatewayIp = i_ipAdrr;
|
connectData.GatewayMac = i_mac;
|
connectData.localEncrypt = localEncrypt;
|
lock (this.listTcpClient)
|
{
|
//找到当前网关的连接
|
if (this.listTcpClient.Find((v) => v.GatewayMac == i_mac) != null)
|
{
|
return;
|
}
|
this.listTcpClient.Add(connectData);
|
}
|
|
try
|
{
|
//TCP连接
|
connectData.tcpClient = new Communication.TcpClient(i_ipAdrr, 8586);
|
connectData.tcpClient.Connect();
|
connectData.tcpClient.ReadFormSocket();
|
connectData.tcpClient.ExitEvent += (s, e) =>
|
{
|
StopConnectLinkGateway(connectData);
|
};
|
connectData.tcpClient.ReceiveBytesAction += (topic, bytes, socket) =>
|
{
|
managerLinkGatewayData(topic, bytes, socket);
|
};
|
|
|
}
|
catch
|
{
|
#if DEBUG
|
//HdlMessageLogic.Current.ShowMassage(ShowMsgType.Tip, i_ipAdrr + "Tcp链接不了");
|
#endif
|
StopConnectLinkGateway(connectData);
|
}
|
}
|
|
public TcpConnectData GetConnectObjectBySocket(Socket socket)
|
{
|
lock (listTcpClient)
|
{
|
var tcpConnectData = listTcpClient.Find(tcd => tcd.tcpClient._socket == socket);
|
return tcpConnectData;
|
}
|
}
|
|
/// <summary>
|
/// 断开全部的Link网关连接
|
/// </summary>
|
public void StopAllConnectLinkGateway()
|
{
|
var listTemp = new List<TcpConnectData>();
|
for (int i = 0; i < this.listTcpClient.Count; i++)
|
{
|
//创另外一个对象出来,是有作用的
|
listTemp.Add(this.listTcpClient[i]);
|
}
|
foreach (var data in listTemp)
|
{
|
//断开指定的link网关连接
|
this.StopConnectLinkGateway(data);
|
}
|
//清空缓存
|
this.listTcpClient.Clear();
|
}
|
|
/// <summary>
|
/// 断开指定的link网关连接
|
/// </summary>
|
/// <param name="mac">需要断开连接的网关mac</param>
|
public void StopConnectLinkGateway(string mac)
|
{
|
var tempGateway = listTcpClient.Find((v) => v.GatewayMac == mac);
|
if (tempGateway != null)
|
{
|
//断开指定的link网关连接
|
this.StopConnectLinkGateway(tempGateway);
|
}
|
}
|
|
/// <summary>
|
/// 断开指定的link网关连接
|
/// </summary>
|
/// <param name="connectData">连接数据</param>
|
private void StopConnectLinkGateway(TcpConnectData connectData)
|
{
|
lock (listTcpClient)
|
{
|
this.listTcpClient.Remove(connectData);
|
connectData.tcpClient.Dispose();
|
}
|
}
|
|
#endregion
|
|
#region ■ 发送数据到Link网关_________________
|
/// <summary>
|
/// 发送数据到本地Link网关
|
/// </summary>
|
/// <param name="connectData">链接信息</param>
|
/// <param name="sendData">发送的数据</param>
|
/// <returns></returns>
|
private void DoSendDataToLinkGateway(TcpConnectData connectData, string sendData)
|
{
|
#if DEBUG
|
MainPage.Log(DateTime.Now + ":TcpClient->DoSendDataToLinkGateway", $"本地发送数据,Data:{sendData}");
|
#endif
|
byte[] byteData;
|
//44bytes 加密数据 AES加密 base64密文
|
////目前默认都是加密载荷
|
//byteData = this.AesEncryptPayload(byteData, Config.Instance.Home.localSecret);
|
//解密负载数据(因为写密钥给网关一定明文,因为那时网关还没有密钥)
|
if (connectData.localEncrypt)
|
{
|
var headerAndBody = sendData.Split("\r\n\r\n");
|
string topic = headerAndBody[0].Split("\r\n")[0];
|
//加密载荷
|
var byteBody = this.AesEncryptPayload(System.Text.Encoding.UTF8.GetBytes(headerAndBody[1]), DB_ResidenceData.Instance.CurrentRegion.localSecret);
|
var header = System.Text.Encoding.UTF8.GetBytes($"{topic}\r\nLength:{byteBody.Length}\r\n" + "\r\n");
|
|
byteData = new byte[header.Length + byteBody.Length];
|
System.Array.Copy(header, 0, byteData, 0, header.Length);
|
///参数(源文件,取源文件索引值,存储器,存放位置,源文件长度)
|
System.Array.Copy(byteBody, 0, byteData, header.Length, byteBody.Length);
|
|
}
|
else
|
{
|
byteData = Encoding.UTF8.GetBytes(sendData);
|
}
|
|
//byteData = Encoding.UTF8.GetBytes(sendData);
|
//将数据写入网络流
|
connectData.tcpClient?.CommSend(byteData, byteData.Length);
|
}
|
|
#endregion
|
|
#region ■ 处理Link网关的数据_________________
|
|
/// <summary>
|
/// 处理接收本地Link网关的数据(返回值 0:还不存在完成的数据 1:已经存在完成的数据)
|
/// </summary>
|
/// <param name="listByte">数据</param>
|
private void managerLinkGatewayData(string topic, byte[] bytes, Socket socket)
|
{
|
try
|
{
|
var arryTopic = topic.Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries);
|
if (arryTopic.Length < 2)
|
{
|
//非正规主题
|
return;
|
}
|
|
|
var connectData = this.GetConnectObjectBySocket(socket);
|
if (connectData == null)
|
{
|
return;
|
}
|
string gatewayMac = connectData.GatewayMac;
|
string gatewayId = connectData.GatewayId;
|
///解密负载数据
|
if (connectData.localEncrypt == true)
|
{
|
var tempBytes = bytes;
|
bytes = this.AesDecryptPayload(bytes, DB_ResidenceData.Instance.CurrentRegion.localSecret);
|
if (bytes == null)
|
{
|
bytes = tempBytes;
|
}
|
}
|
/////目前网关默认都是加密的
|
//bytes = this.AesDecryptPayload(bytes, Config.Instance.Home.localSecret);
|
var bodyData = System.Text.Encoding.UTF8.GetString(bytes);
|
|
MainPage.Log(DateTime.Now + ":Control_Tcp->本地接收数据", $"Topic:{topic}\r\nData:{bodyData}");
|
|
if (topic.Contains("thing/property/up") == true)
|
{
|
//这个是Link设备的状态上报,别整,只要zigbee的
|
var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<AlinkFunctionStatusObj>(bodyData);
|
|
return;
|
}
|
|
}
|
catch (Exception e)
|
{
|
}
|
}
|
|
|
#endregion
|
|
#region ■ 结构体_____________________________
|
|
|
/// <summary>
|
/// Tcp连接信息
|
/// </summary>
|
public class TcpConnectData
|
{
|
/// <summary>
|
/// 网关的mac(主键使用)
|
/// </summary>
|
public string GatewayMac = string.Empty;
|
/// <summary>
|
/// 网关ip
|
/// </summary>
|
public string GatewayIp = string.Empty;
|
/// <summary>
|
/// 网关Id(不是云端的那个)
|
/// </summary>
|
public string GatewayId = string.Empty;
|
|
//
|
public Communication.TcpClient tcpClient;
|
|
/// <summary>
|
/// 本地是否加密
|
/// </summary>
|
public bool localEncrypt;
|
}
|
#endregion
|
|
#region ■ 加密以及解密_______________________
|
|
/// <summary>
|
/// 加密负载为二进制流(Link专用)
|
/// </summary>
|
/// <param name="toEncryptArray"></param>
|
/// <param name="key"></param>
|
/// <returns></returns>
|
private byte[] AesEncryptPayload(byte[] toEncryptArray, string key)
|
{
|
//加密密钥为空
|
if (key == string.Empty)
|
{
|
return toEncryptArray;
|
}
|
try
|
{
|
if (string.IsNullOrEmpty(key)) return toEncryptArray;
|
//配置AES加密Key(密钥、向量、模式、填充)
|
var rm = new System.Security.Cryptography.RijndaelManaged
|
{
|
Key = Encoding.UTF8.GetBytes(key),
|
IV = Encoding.UTF8.GetBytes(key),
|
Mode = System.Security.Cryptography.CipherMode.CBC,
|
Padding = System.Security.Cryptography.PaddingMode.PKCS7
|
};
|
|
//创建AES加密器对象
|
var cTransform = rm.CreateEncryptor();
|
//使用AES将明文流转成密文字节数组
|
return cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
|
}
|
catch
|
{
|
return null;
|
}
|
}
|
|
/// <summary>
|
/// 采用Aes解密负载数据(Link专用)
|
/// </summary>
|
/// <param name="toEncryptArray"></param>
|
/// <param name="key"></param>
|
/// <returns></returns>
|
private byte[] AesDecryptPayload(byte[] toEncryptArray, string key)
|
{
|
//解密密钥为空
|
if (key == string.Empty)
|
{
|
return toEncryptArray;
|
}
|
|
try
|
{
|
//配置AES加密Key(密钥、向量、模式、填充)
|
var rm = new System.Security.Cryptography.RijndaelManaged
|
{
|
Key = Encoding.UTF8.GetBytes(key),
|
IV = Encoding.UTF8.GetBytes(key),
|
Mode = System.Security.Cryptography.CipherMode.CBC,
|
Padding = System.Security.Cryptography.PaddingMode.PKCS7
|
};
|
|
//创建AES解密器对象
|
var cTransform = rm.CreateDecryptor();
|
|
//使用AES将密文流转成明文的字节数组
|
return cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
|
}
|
catch
|
{
|
return null;
|
}
|
}
|
|
#endregion
|
|
}
|
}
|
namespace Communication
|
{
|
//TCP客户端实现
|
public class TcpClient
|
{
|
private const int MAX_RECONNECT_TIMES = 3; //断线重连尝试次数
|
|
//soket对象及参数
|
public Socket _socket;
|
private string host;
|
private int port;
|
private bool reconnect;
|
private bool run = true;
|
private int ConnecteFailedCount { get; set; }
|
public int ReconnectStatistics { get; private set; }
|
|
private static uint _keepAliveTime = 5000; //无数据交互持续时间(ms)
|
private static uint _keepAliveInterval = 500; //发送探测包间隔(ms)
|
|
//重连失败事件
|
public event EventHandler ExitEvent;
|
public Action<string, byte[], Socket> ReceiveBytesAction;
|
|
//构造函数
|
public TcpClient(string host, int port)
|
{
|
this.host = host;
|
this.port = port;
|
reconnect = false;
|
ConnecteFailedCount = 0;
|
}
|
|
//连接
|
public void Connect()
|
{
|
byteList = new List<byte>(1024 * 5);
|
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
|
ProtocolType.Tcp);
|
_socket.Connect(host, port);
|
MainPage.Log("TcpClient->Reconnect", $"连接成功,IP:{host}");
|
ConnecteFailedCount = MAX_RECONNECT_TIMES;
|
|
//设置KeepAlive
|
_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
|
byte[] optionValue = new byte[12];
|
BitConverter.GetBytes(1).CopyTo(optionValue, 0);
|
BitConverter.GetBytes(_keepAliveTime).CopyTo(optionValue, 4);
|
BitConverter.GetBytes(_keepAliveInterval).CopyTo(optionValue, 8);
|
_socket.IOControl(IOControlCode.KeepAliveValues, optionValue, null);
|
}
|
|
//重连
|
public bool Reconnect()
|
{
|
ReconnectStatistics++;
|
reconnect = false;
|
close();
|
try
|
{
|
MainPage.Log("TcpClient->Reconnect", $"重新开始连接,IP:{host}");
|
Connect();
|
}
|
catch (Exception e)
|
{
|
ConnecteFailedCount--;
|
if (ConnecteFailedCount > 0)
|
{
|
//Console.WriteLine("重试次数剩余{0}",ConnecteFailedCount);
|
reconnect = true;
|
return true;
|
}
|
else
|
{
|
//重连失败事件
|
return false;
|
}
|
}
|
return true;
|
}
|
|
/// <summary>
|
/// 关闭
|
/// </summary>
|
private void close()
|
{
|
try
|
{
|
MainPage.Log("TcpClient->Close", $"Socket 关闭,IP:{host}");
|
_socket.Close();
|
}
|
catch { }
|
}
|
|
|
/// <summary>
|
/// 释放资源
|
/// </summary>
|
public void Dispose()
|
{
|
run = false;
|
close();
|
}
|
|
|
//发送数据接收实现,断线重连
|
public int CommSend(byte[] buffer, int size)
|
{
|
int sendSize = 0;
|
try
|
{
|
if (_socket.Connected)
|
{
|
sendSize = _socket.Send(buffer, size, SocketFlags.None);
|
}
|
}
|
catch (Exception e)
|
{
|
MainPage.Log("TcpClient->CommSend", $"发送失败,Data:{System.Text.Encoding.UTF8.GetString(buffer)} Exception:{e.Message}");
|
ReconnectStatistics++;
|
reconnect = true;
|
}
|
return sendSize;
|
}
|
|
List<byte> byteList = new List<byte>();
|
//接收数据线程,使用阻塞方式接收数据
|
public void ReadFormSocket()
|
{
|
new System.Threading.Thread(() =>
|
{
|
int count;
|
byte[] byteBuffer = new byte[2048];
|
|
while (run)
|
{
|
try
|
{
|
try
|
{
|
count = _socket.Receive(byteBuffer, SocketFlags.None);
|
for (int i = 0; i < count; i++)
|
{
|
byteList.Add(byteBuffer[i]);
|
}
|
}
|
catch (Exception e)
|
{
|
count = 0;
|
}
|
|
//网络断开Receive返回0
|
if (count == 0 || reconnect == true)
|
{
|
if (run)
|
{
|
//重连次数用尽,退出
|
if (Reconnect() == false)
|
{
|
//通知其它功能释放及删除当前对象
|
ExitEvent?.Invoke(null, new EventArgs());
|
break;
|
}
|
}
|
else
|
{
|
ExitEvent?.Invoke(null, new EventArgs());
|
}
|
}
|
else
|
{
|
|
while (true)
|
{
|
var bytes = byteList.ToArray();
|
var topMsgs = System.Text.Encoding.UTF8.GetString(bytes).Split("\r\n");
|
|
var lenght = getLenght(topMsgs);
|
|
if (lenght <= 0)
|
{
|
//头部数据还没有接收完成
|
break;
|
}
|
//是否已经获取完整所有的数据
|
var data = new byte[lenght];
|
int index = getDataIndex(byteList);
|
if (byteList.Count < index + lenght)
|
{
|
//当前数据还没有接收完成
|
break;
|
}
|
//复制出body数据
|
System.Array.Copy(bytes, index, data, 0, data.Length);
|
|
//保留剩余的数据,以次用
|
byteList.Clear();
|
for (int i = index + lenght; i < bytes.Length; i++)
|
{
|
byteList.Add(bytes[i]);
|
}
|
var topic = getTopic(topMsgs);
|
|
ReceiveBytesAction?.Invoke(topic, data, _socket);
|
}
|
}
|
}
|
catch (Exception e)
|
{
|
MainPage.Log("TcpClient->ReadFormSocket", $"Exception:{e.Message}");
|
}
|
}
|
})
|
{
|
IsBackground = true
|
}.Start();
|
|
}
|
|
/// <summary>
|
/// 获取内容长度
|
/// </summary>
|
/// <param name="topMsgs"></param>
|
/// <returns></returns>
|
int getLenght(string[] topMsgs)
|
{
|
for (int i = 0; i < topMsgs.Length; i++)
|
{
|
string topMsg = topMsgs[i].Trim();
|
if (topMsg.StartsWith("Length:"))
|
{
|
return int.Parse(topMsg.Replace("Length:", ""));
|
}
|
}
|
//找不到长度
|
return -1;
|
}
|
|
/// <summary>
|
/// 获取主题
|
/// </summary>
|
/// <param name="topMsgs"></param>
|
/// <returns></returns>
|
private string getTopic(string[] topMsgs)
|
{
|
for (int i = 0; i < topMsgs.Length; i++)
|
{
|
var topMsg = topMsgs[i].Trim();
|
if (topMsg.StartsWith("Topic:"))
|
{
|
return topMsg.Replace("Topic:", "");
|
}
|
}
|
//找不到主题
|
return null;
|
}
|
|
/**
|
* 获取数据的开始位置
|
* @param arrayList 接收到的所有数据
|
* @return 数据位的开始索引
|
*/
|
int getDataIndex(List<byte> arrayList)
|
{
|
var r = (byte)'\r';
|
var n = (byte)'\n';
|
for (int i = 0; i < arrayList.Count; i++)
|
{
|
//找出数据内容前面的两个换行
|
if (3 <= i && arrayList[i - 3] == r && arrayList[i - 2] == n && arrayList[i - 1] == r && arrayList[i] == n)
|
{
|
//剩余的数据
|
return i + 1;
|
}
|
}
|
return -1;
|
}
|
|
|
}
|
}
|