Socket TCP
Demo
private readonly TcpHelper _tcpHelper;
public ctor()
{
_tcpHelper = new TcpHelper();
_tcpHelper.DataReceivedEvent += TcpClient_DataReceivedEvent;
if (_tcpHelper.TcpInit("192.16.1.23", "6000"))
{
_tcpHelper.SetStartIdentifier(null);
_tcpHelper.SetEndIdentifier(Encoding.UTF8.GetBytes("*"));
var cmd = WSCommFunc.SerializeWithCamel(request);
_tcpHelper.TcpSend(cmd);
}
}
public void TcpClient_DataReceivedEvent(object sender, EventArgs e)
{
if (e is CommTcpEventArgs args)
{
switch (args.State)
{
case CommTcpStateType.Open:
{
ShowLogInfo("tcp已连接上.");
}
break;
case CommTcpStateType.Error:
{
ShowLogInfo("tcp发生错误! 信息:" + args.Message);
}
break;
case CommTcpStateType.Close:
{
ShowLogInfo("tcp已关闭.");
}
break;
case CommTcpStateType.Connect:
var message = Encoding.UTF8.GetString(args.Message);
ShowLogInfo(message);
break;
default:
break;
}
}
}
TcpHelper
/// <summary>
/// Tcp通信帮助类(有帧头、帧尾检测)
/// </summary>
internal sealed class TcpHelper
{
private readonly WeakEvent<EventArgs> _dataReceivedEvent = new WeakEvent<EventArgs>();
/// <summary>
/// 返回的消息数据弱事件
/// </summary>
public event EventHandler<EventArgs> DataReceivedEvent
{
add => _dataReceivedEvent.Add(value, value.Invoke);
remove => _dataReceivedEvent.Remove(value);
}
public bool IsOpen => _client != null && _client.IsOpen;
public string IP { get; set; }
public string Port { get; set; }
private CustomTcp _client;
/// <summary>
/// 帧头累加和,适用于 有帧头无帧尾
/// </summary>
private byte _startIdentifierSum;
public TcpHelper()
{
_startIdentifierSum = 0;
}
/// <summary>
/// 设置结尾标识符
/// </summary>
/// <param name="end"></param>
public void SetEndIdentifier(byte[] end)
{
if (_client != null)
{
_client.EndIdentifier = end;
}
}
/// <summary>
/// 设置开始标识符
/// </summary>
/// <param name="start"></param>
public void SetStartIdentifier(byte[] start)
{
if (_client != null)
{
_client.StartIdentifier = start;
if (start == null)
{
_startIdentifierSum = 0;
}
else
{
_startIdentifierSum = WSCommFunc.GetSum(start);
}
}
}
/// <summary>
/// Tcp初始化
/// </summary>
/// <param name="ip"></param>
/// <param name="port"></param>
public bool Init(string ip, string port)
{
IP = ip;
Port = port;
_client = new CustomTcp();
_client.DataReceivedEvent += TcpClient_DataReceivedEvent;
return _client.Open(ip, port);
}
/// <summary>
/// 关闭连接
/// </summary>
public void Close()
{
if (_client != null)
{
_client.DataReceivedEvent -= TcpClient_DataReceivedEvent;
_client.Close();
_client = null;
}
}
/// <summary>
/// 发送命令
/// </summary>
/// <param name="cmd">命令内容</param>
public void Send(string cmd)
{
if (_client != null)
{
try
{
_client.Send(cmd);
}
catch (Exception ex)
{
LogFactory.GetInstance().Error("tcp发送信息发生异常:", ex);
}
}
}
/// <summary>
/// 发送命令
/// </summary>
/// <param name="data">命令内容</param>
public void Send(byte[] data)
{
if (_client != null)
{
try
{
_client.Send(data);
}
catch (Exception ex)
{
LogFactory.GetInstance().Error("tcp发送信息发生异常:", ex);
}
}
}
/// <summary>
/// 发送命令(带数据累加和校验,包含帧头)
/// </summary>
/// <param name="data"></param>
/// <param name="identifier">功能码</param>
public void SendSumCheckWithHead(byte[] data, ControllerIdentifiers identifier)
{
// 通信命令格式: 起始符(88) + 功能码 + 数据长度(mod 255) + 数据内容(DATA) + 数据校验(前面所有字节和)
int len = data.Length % 255;
int sum = _startIdentifierSum + (int)identifier + len + WSCommFunc.GetSum(data);
List<byte> tmp = new List<byte>(data.Length + 3) { (byte)identifier, (byte)len };
tmp.AddRange(data);
tmp.Add((byte)sum);
if (IsOpen)
{
_client.Send(tmp.ToArray());
}
}
/// <summary>
/// 获取的数据校验(带数据累加和校验,包含帧头)
/// </summary>
/// <param name=""></param>
/// <returns>true校验成功</returns>
public bool DataSumCheckWithHead(byte[] data)
{
// 数据格式: 功能码 + 数据长度(mod 255) + 数据内容(DATA) + 数据校验
int length = data.Length;
if (length <= 3)
{
return false;
}
// 长度不一致,异常数据
if (data[1] != length - 3)
{
return false;
}
byte[] temp = new byte[length - 1];
Array.Copy(data, 0, temp, 0, length - 1);
byte sum = (byte)(_startIdentifierSum + WSCommFunc.GetSum(temp));
return sum == data[length - 1];
}
private void TcpClient_DataReceivedEvent(object sender, EventArgs e)
{
_ = _dataReceivedEvent.Invoke(this, e);
}
}
/// <summary>
/// 设备的功能码
/// </summary>
internal enum ControllerIdentifiers
{
/// <summary>
/// -, 返回0xA0
/// </summary>
[VersionData("A0")]
心跳包 = 0xA0,
/// <summary>
/// 0xBB, 返回0xAB
/// </summary>
[VersionData("AB")]
设置本地参数 = 0xBB,
/// <summary>
/// 0xBC, 返回0xAC
/// </summary>
[VersionData("AC")]
读取本地参数 = 0xBC,
}
其中,CustomTcp是基于SuperSocket.ClientEngine的封装,可自行实现。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!