【问题标题】:Chunking a message into smaller chunks in C#在 C# 中将消息分块成更小的块
【发布时间】:2016-12-22 06:58:47
【问题描述】:

我有一个 C# 类来创建消息。

    public class ExMessage
    {
        private UInt16 m_SendingId = 123;
        private byte m_control_byte_1;
        private enum destination_service : byte
        {
          serv_1 = 0x0,
          serv_2 = 0x1
        };
        private byte m_pd;
        private byte m_filler_bytes;
        private byte[] m_payload;

        public byte[] Payload
        {
            get
            {
                return m_payload;
            }
        }


        /// <summary>
        /// Constructor.
        /// </summary>
        public ExMessage(byte[] payload)
        {
            m_pd = 0x0;
            m_control_byte_1 = 0xA5;
            m_payload = payload;
            m_filler_bytes = 0xF;

        }

        protected void WriteBody(Stream stream)
        {
            stream.WriteByte(m_control_byte_1); 
            stream.WriteByte(0x0); 

            stream.WriteWordLittleEndian(m_SendingId); 
            stream.WriteByte((byte)destination_service.serv_2); 

            stream.WriteByte((byte)m_pd); // payload details

            stream.WriteByte((byte)m_payload.Length); //write the payload length

            var count = 0;
            while (count < m_payload.Length)  //copy over the actual payload.
            {
                stream.WriteByte((byte)m_payload[count]);
                count++;
            }

            var len = 48 - (5 + m_payload.Length);
            count = 0;
            while (count < len) //copy over spare bytes 0x3
            {
                stream.WriteByte(m_filler_bytes);
                count++;
            }
        }

        public byte[] ToBytes()
        {
            MemoryStream stream = new MemoryStream();
            WriteBody(stream);

            return stream.ToArray();
        }

我按如下方式创建消息

 var Message = new ExMessage(Encoding.UTF8.GetBytes("HelloWorld"));

现在我的使用场景如下。

1) 我使用的协议对有效负载施加了 40 字节的大小限制。如果我传递的有效负载中的字节数大于40 字节,则应将其拆分为两条消息。

2) 构造函数有没有办法根据我传递给它的字节数组的大小返回ExMessage 对象列表。

3) 如果不是,那么处理这种情况的最佳方法是什么

【问题讨论】:

  • 一些 cmets,在某种程度上独立于问题: - 如果您事先不知道大小,则增量写入 MemoryStream 效率低下。这是因为调整了内部缓冲区的大小。看来在这里你会知道的。鉴于此,预先调整流的大小以确保它对于整个块来说足够长,即使您以增量方式编写它也是如此。 - 小心让单个 MemoryStream 变得太大。查看 .net 中有关大型对象的文档 - 不要从 m_payload 增量写入,而是通过一次 Write() 调用一次写入整个块

标签: c# messages


【解决方案1】:

我会这样做:

var size = 4;
var messages =
    Encoding.UTF8.GetBytes("HelloWorld") //48 65 6C 6C 6F 57 6F 72 6C 64
        .Select((b, i) => new { b, i }) // Enumerable of byte and index
        .GroupBy(x => x.i / size, x => x.b) // group by index divide by block size
        .Select(x => new ExMessage(x.ToArray())); // create messages

这给了我:

你可以这样实现它:

public class ExMessage
{
    private const int __size = 4;
    public static ExMessage[] Create(byte[] payload)
    {
        return payload
            .Select((b, i) => new { b, i })
              .GroupBy(x => x.i / __size, x => x.b)
              .Select(x => new ExMessage(x.ToArray()))
              .ToArray();
    }
    /* rest of class */
}

然后你可以这样称呼它:

var messages = ExMessage.Create(Encoding.UTF8.GetBytes("HelloWorld"));

【讨论】:

  • 以上方案需要什么包。它需要 C# Reactive 扩展吗?如果是这样,我宁愿避免它。
  • @liv2hak - 不,这只是标准 LINQ。
  • 我不太明白其中的逻辑。能不能再给我解释一下
  • 我需要将chunk number 传递给我的构造函数ExMessage()
  • @liv2hak - 你在 ExMessage 的构造函数中没有块号,但如果你需要添加它,它看起来像这样:.Select(x =&gt; new ExMessage(x.Key, x.ToArray()))
【解决方案2】:

没有。

我会在 ExMessage 上使用静态函数,如下所示:

class ExMessage
{
   ...
   public static List<ExMessage> CreateMessages(byte[] payload)
   {
      List<byte[]> chunks = ... split payload into 40byte chunks...
      return chunks.Select(p => new ExMessage(p).ToList();     
   }
   ...
}

【讨论】:

    猜你喜欢
    • 2011-03-27
    • 2012-04-27
    • 2022-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-06
    • 2016-05-05
    • 2021-11-11
    相关资源
    最近更新 更多