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.

150 lines
5.0 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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;
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);
//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();
new Decode().decode(ipAddress, port, bytes);
}
else //不加密
{
new Decode().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;
}
}
}