You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

151 lines
5.0 KiB

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DotNetty.Buffers;
using DotNetty.Codecs;
using DotNetty.Transport.Channels;
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using HybirdFrameworkEntity;
8 months ago
using BatCharging.Service;
namespace Module.Socket.Tool
{
public class CustomFrameDecoder4 : ByteToMessageDecoder
{
private readonly IByteBuffer[] delimiters;
private readonly bool stripDelimiter;
private readonly bool failFast;
public CustomFrameDecoder4(IByteBuffer[] delimiters, bool stripDelimiter, bool failFast)
{
this.delimiters = delimiters;
this.stripDelimiter = stripDelimiter;
this.failFast = failFast;
}
protected override void Decode(IChannelHandlerContext ctx, IByteBuffer buffer, List<object> output)
{
// 查找分隔符
IByteBuffer delimiter = FindDelimiter(buffer);
if (delimiter != null)
{
int delimiterIndex = IndexOf(buffer, delimiter);//分隔符索引
int frameLengthIndex = delimiterIndex + delimiter.Capacity;//帧长度索引
if (delimiterIndex > 0)
{
buffer.SkipBytes(delimiterIndex);
return;
}
if (buffer.ReadableBytes < frameLengthIndex + 7)
{
// 数据不足,等待更多数据
return;
}
// 读取长度字段
int frameLength = buffer.GetUnsignedShortLE(buffer.ReaderIndex + frameLengthIndex);
int totalFrameLength = delimiterIndex + delimiter.Capacity + 2 + frameLength;
if (buffer.ReadableBytes < totalFrameLength)
{
// 数据不足,等待更多数据
return;
}
byte[] bytes = new byte[frameLength];
buffer.ReadBytes(bytes);
{
string input = ctx.Channel.RemoteAddress.ToString();
// 正则表达式匹配IPv4地址和端口号
string pattern = @"\[(::ffff:)?(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\]:(\d+)";
Match match = Regex.Match(input, pattern);
// 获取IP地址不包括IPv6前缀
string ipAddress = match.Groups[2].Value;
// 获取端口号
string port = match.Groups[3].Value;
int checksum = 0;
for (int i = 6; i < bytes.Count() - 1; i++)//这里有校验域所以减一
{
checksum += bytes[i];
}
// 取校验和的低8位
//byte b1 = (byte)(checksum & 0xFF);
8 months ago
//byte b2 = (byte)(bytes[bytes.Count() - 1] & 0xFF);
if ((byte)(bytes[bytes.Count() - 1] & 0xFF) == (byte)(checksum & 0xFF))
{
var info = bytes[4];
if ((info & (1 << 1)) != 0)//AES加密
{
//这里要解密
List<byte> byteList = bytes.ToList();
byteList.Remove(8);
byteList.Remove(8);//移除前面两个长度
bytes = byteList.ToArray();
8 months ago
new ChargerMgrTool().decode(ipAddress, port, bytes);
}
else //不加密
{
8 months ago
new ChargerMgrTool().decode(ipAddress, port, bytes);
}
}
//ctx.Channel.WriteAndFlushAsync(bytes);
}
output.Add(bytes);
}
}
private IByteBuffer FindDelimiter(IByteBuffer buffer)
{
foreach (IByteBuffer delimiter in delimiters)
{
int delimiterIndex = IndexOf(buffer, delimiter);
if (delimiterIndex >= 0)
{
return delimiter;
}
}
return null;
}
private static int IndexOf(IByteBuffer haystack, IByteBuffer needle)
{
for (int i = haystack.ReaderIndex; i < haystack.WriterIndex; i++)
{
int num = i;
int j;
for (j = 0; j < needle.Capacity && haystack.GetByte(num) == needle.GetByte(j); j++)
{
num++;
if (num == haystack.WriterIndex && j != needle.Capacity - 1)
{
return -1;
}
}
if (j == needle.Capacity)
{
return i - haystack.ReaderIndex;
}
}
return -1;
}
}
}