/*
* 该类用于管理tcp作为服务端连接通讯
*/
using System;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Threading;
using System.Net;
using Shared;
using HDL_ON.Entity;
namespace HDL_ON.DriverLayer
{
///
/// TCP服务端
///
public class Control_TcpServer
{
private Socket ServerSocket = null;//服务端
public Dictionary dic_ClientSocket = new Dictionary();//tcp客户端字典
private Dictionary dic_ClientThread = new Dictionary();//线程字典,每新增一个连接就添加一条线程
private bool Flag_Listen = true;//监听客户端连接的标志
///
/// 启动服务
///
/// 端口号
public bool OpenServer(int port = 8586)
{
try
{
Flag_Listen = true;
// 创建负责监听的套接字,注意其中的参数;
ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// 创建包含ip和端口号的网络节点对象;
IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, port);
try
{
// 将负责监听的套接字绑定到唯一的ip和端口上;
ServerSocket.Bind(endPoint);
}
catch
{
return false;
}
// 设置监听队列的长度;
ServerSocket.Listen(100);
// 创建负责监听的线程;
Thread Thread_ServerListen = new Thread(ListenConnecting);
Thread_ServerListen.IsBackground = true;
Thread_ServerListen.Start();
MainPage.Log("启动tcp侦听");
return true;
}
catch
{
return false;
}
}
///
/// 关闭服务
///
public void CloseServer()
{
lock (dic_ClientSocket)
{
foreach (var item in dic_ClientSocket)
{
item.Value.Close();//关闭每一个连接
}
dic_ClientSocket.Clear();//清除字典
}
lock (dic_ClientThread)
{
foreach (var item in dic_ClientThread)
{
item.Value.Abort();//停止线程
}
dic_ClientThread.Clear();
}
Flag_Listen = false;
//ServerSocket.Shutdown(SocketShutdown.Both);//服务端不能主动关闭连接,需要把监听到的连接逐个关闭
if (ServerSocket != null)
ServerSocket.Close();
}
///
/// 监听客户端请求的方法;
///
private void ListenConnecting()
{
while (Flag_Listen) // 持续不断的监听客户端的连接请求;
{
try
{
Socket sokConnection = ServerSocket.Accept(); // 一旦监听到一个客户端的请求,就返回一个与该客户端通信的 套接字;
// 将与客户端连接的 套接字 对象添加到集合中;
string str_EndPoint = sokConnection.RemoteEndPoint.ToString();
MySession myTcpClient = new MySession() { TcpSocket = sokConnection };
//创建线程接收数据
Thread th_ReceiveData = new Thread(ReceiveData);
th_ReceiveData.IsBackground = true;
th_ReceiveData.Start(myTcpClient);
//把线程及客户连接加入字典
dic_ClientThread.Add(str_EndPoint, th_ReceiveData);
dic_ClientSocket.Add(str_EndPoint, myTcpClient);
}
catch
{
}
Thread.Sleep(200);
}
}
///
/// 接收数据
///
///
private void ReceiveData(object sokConnectionparn)
{
MySession tcpClient = sokConnectionparn as MySession;
Socket socketClient = tcpClient.TcpSocket;
bool Flag_Receive = true;
while (Flag_Receive)
{
try
{
// 定义一个2M的缓存区;
byte[] arrMsgRec = new byte[1024 * 1024 * 2];
// 将接受到的数据存入到输入 arrMsgRec中;
int length = -1;
try
{
length = socketClient.Receive(arrMsgRec); // 接收数据,并返回数据的长度;
}
catch (Exception ex)
{
MainPage.Log($"tcpListener error 1 : {ex.Message}");
Flag_Receive = false;
// 从通信线程集合中删除被中断连接的通信线程对象;
string keystr = socketClient.RemoteEndPoint.ToString();
dic_ClientSocket.Remove(keystr);//删除客户端字典中该socket
dic_ClientThread[keystr].Abort();//关闭线程
dic_ClientThread.Remove(keystr);//删除字典中该线程
tcpClient = null;
socketClient = null;
break;
}
byte[] buf = new byte[length];
Array.Copy(arrMsgRec, buf, length);
lock (tcpClient.m_Buffer)
{
//tcpClient.m_Buffer.Add(buf);
var tcpDataString = System.Text.Encoding.UTF8.GetString(arrMsgRec, 0, length);
if (!string.IsNullOrEmpty(tcpDataString))
{
AnalysisTcpData(socketClient, tcpDataString);
}
MainPage.Log(tcpDataString);
}
}
catch (Exception ex)
{
MainPage.Log($"tcpListener error 2 : {ex.Message}");
}
Thread.Sleep(100);
}
}
///
/// 获取列表数据回调方法
///
public Action GetListResponseAction;
string tcpFunctionOidJsonString = "";
///
/// 处理tcp数据
///
void AnalysisTcpData(Socket socket, string tcpBodyDataString)
{
MainPage.Log($"0001 tcpDataString:\r\n {tcpBodyDataString}");
var tcpDataObj = Control.Ins.AnalysisReceiveData(tcpBodyDataString);
if (tcpDataObj.BodyDataString == null)
{
return;
}
switch (tcpDataObj.Topic)
{
case CommunicationTopic.AddDeviceOids:
tcpFunctionOidJsonString = tcpDataObj.BodyDataString;
break;
case CommunicationTopic.AddFunctions:
var addSidFunction = Newtonsoft.Json.JsonConvert.DeserializeObject(tcpDataObj.BodyDataString);
Application.RunOnMainThread(() =>
{
var tipDialog = new UI.UpdataSidDataDialog();
var tcpLocalFunction = Newtonsoft.Json.JsonConvert.DeserializeObject>(Newtonsoft.Json.JsonConvert.SerializeObject(addSidFunction.objects));
tipDialog.ShowDialog(tcpLocalFunction, tcpFunctionOidJsonString);
});
break;
case CommunicationTopic.BusPcGetAppOids:
var bytes = Common.FileUtlis.Files.ReadFile(DB_ResidenceData.OidSavePathName);
if (bytes.Length > 0)
{
socket.Send(bytes);
MainPage.Log($"send oid list to 8586 prot :{ System.Text.Encoding.UTF8.GetString(bytes)}");
}
break;
case CommunicationTopic.BusPcGetAppSids:
var sendSidObj = new TcpTransmissionSidsObj();
sendSidObj.id = Control.Ins.msg_id.ToString();
sendSidObj.time_stamp = "";
//转换成bus需要的数据格式
var localFunction = FunctionList.List.GetDeviceFunctionList();
var localFunctionString = Newtonsoft.Json.JsonConvert.SerializeObject(localFunction);
var tcpFunction = Newtonsoft.Json.JsonConvert.DeserializeObject>(localFunctionString);
sendSidObj.objects.AddRange(tcpFunction);
var sendSidJson = Newtonsoft.Json.JsonConvert.SerializeObject(sendSidObj);
var sendSidBytes = System.Text.Encoding.UTF8.GetBytes(sendSidJson);
socket.Send(sendSidBytes, sendSidBytes.Length, SocketFlags.OutOfBand);
MainPage.Log($"send sid list to 8586 prot :{sendSidJson}");
break;
}
}
///
/// 发送数据给指定的客户端
///
/// 客户端套接字
/// 发送的数组
///
public bool SendData(string _endPoint, byte[] _buf)
{
MySession myT = new MySession();
if (dic_ClientSocket.TryGetValue(_endPoint, out myT))
{
myT.Send(_buf);
return true;
}
else
{
return false;
}
}
}
///
/// 会话端
///
public class MySession
{
public Socket TcpSocket;//socket对象
public List m_Buffer = new List();//数据缓存区
public MySession()
{
}
///
/// 发送数据
///
///
public void Send(byte[] buf)
{
if (buf != null)
{
TcpSocket.Send(buf);
}
}
///
/// 获取连接的ip
///
///
public string GetIp()
{
IPEndPoint clientipe = (IPEndPoint)TcpSocket.RemoteEndPoint;
string _ip = clientipe.Address.ToString();
return _ip;
}
///
/// 关闭连接
///
public void Close()
{
TcpSocket.Shutdown(SocketShutdown.Both);
}
///
/// 提取正确数据包
///
public byte[] GetBuffer(int startIndex, int size)
{
byte[] buf = new byte[size];
m_Buffer.CopyTo(startIndex, buf, 0, size);
m_Buffer.RemoveRange(0, startIndex + size);
return buf;
}
///
/// 添加队列数据
///
///
public void AddQueue(byte[] buffer)
{
m_Buffer.AddRange(buffer);
}
///
/// 清除缓存
///
public void ClearQueue()
{
m_Buffer.Clear();
}
}
///
/// bus软件传输功能的sid列表对象
///
public class TcpTransmissionSidsObj
{
public List objects = new List();
public string id = "";
public string time_stamp = "";
}
///
/// bus软件传输的功能对象
/// 仅在与bus软件传递数据时使用,
/// Function对象包含了该对象的所有内容,
/// 此对象为了减少传输数据使用
///
public class BusSidObj
{
public string sid = "";// "0301011234567801012301230123";
///
/// A协议功能的属性
/// 如:是AC功能:属性:on_off,mode,fan,temperature
///
public List attributes = new List();
///
/// 备注
///
public string name;
public string omodel;
}
}