sockets - 从字节数组中解码分隔帧
问题描述
我有由字节分隔的帧来启动和停止帧(它们不会出现在流中)。
我从磁盘或网络套接字读取了一个块,然后我需要传递给一个解串器,但只有在我首先对数据包进行解帧之后。
帧可能跨越多个已读取的块,请注意第 3 帧是如何拆分到array 1
和array 2
的。
与其为这个常见问题重新发明轮子,是否存在任何 github 或类似项目?
我正在ReadOnlySequenceSegment<T>
从https://www.codemag.com/article/1807051/Introducing-.NET-Core-2.1-Flagship-Types-Span-T-and-Memory-T进行调查,并将在制定要求时发布更新.
更新
除了 Stephen Cleary 链接(谢谢!!)到https://github.com/davidfowl/TcpEcho/blob/master/src/Server/Program.cs我有以下内容。
我的数据是 json,因此与原始问题不同,分隔符标记将出现在流中。因此,我必须计算数组分隔符,并且只有在找到最外层[
和]
字符时才声明一个框架。
下面的代码有效,并且完成的手动副本更少(不确定是否仍然在幕后完成 - 使用 David Fowl 方法的代码非常整洁)。
但是,我正在转换为数组而不是使用,buffer.PositionOf((byte)'[')
因为我无法看到如何在PositionOf
应用了偏移量的情况下调用 (即更深入地扫描过去找到的分隔符标记的帧)。
我是否以蛮力的方式使用/屠宰图书馆,或者下面的阵列是否适合使用?
class Program
{
static async Task Main(string[] args)
{
using var stream = File.Open(args[0], FileMode.Open);
var reader = PipeReader.Create(stream);
while (true)
{
ReadResult result = await reader.ReadAsync();
ReadOnlySequence<byte> buffer = result.Buffer;
while (TryDeframe(ref buffer, out ReadOnlySequence<byte> line))
{
// Process the line.
var str = System.Text.Encoding.UTF8.GetString(line.ToArray());
Console.WriteLine(str);
}
// Tell the PipeReader how much of the buffer has been consumed.
reader.AdvanceTo(buffer.Start, buffer.End);
// Stop reading if there's no more data coming.
if (result.IsCompleted)
{
break;
}
}
// Mark the PipeReader as complete.
await reader.CompleteAsync();
}
private static bool TryDeframe(ref ReadOnlySequence<byte> buffer, out ReadOnlySequence<byte> frame)
{
int frameCount = 0;
int start = -1;
int end = -1;
var bytes = buffer.ToArray();
for (var i = 0; i < bytes.Length; i++)
{
var b = bytes[i];
if (b == (byte)'[')
{
if (start == -1)
start = i;
frameCount++;
}
else if (b == (byte)']')
{
frameCount--;
if (frameCount == 0)
{
end = i;
break;
}
}
}
if (start == -1 || end == -1) // no frame found
{
frame = default;
return false;
}
frame = buffer.Slice(start, end+1);
buffer = buffer.Slice(frame.Length);
return true;
}
}
解决方案
是否存在任何 github 或类似项目?
David Fowler 有一个回显服务器,它使用管道来实现分隔帧。
推荐阅读
- c# - 椭圆变成长方形
- linux - 稍后在分配变量后使用变量引用扩展字符串
- node.js - 无法在 angular4 中使用数组到树的 npm 模块
- mysql - MySQL Workbench 查询返回 1 行,但 Jdbc 中的相同查询返回 0
- c# - 执行在数据集的 .xsd 中配置的存储过程
- google-api - cse 热门查询与谷歌搜索结果中的显示不完全相同
- python - 外部终端和VSCode之间的Python3不同
- c# - 下拉菜单在 View MVC 上不显示数据
- android - 如果 Glide 无法连接到远程服务器,Android 片段会从 drawable 中加载默认图像
- c - 交互式、限制性、动态的用户输入