0

我正在尝试按顺序发送与数字 1-1000 相对应的 UDP 字节数据包。如何将每个数字 (1,2,3,4,...,998,999,1000) 转换为所需的最小字节数,并将它们放在可以作为 UDP 数据包发送的序列中?

我尝试了以下但没有成功。任何帮助将不胜感激!

 List<byte> byteList = new List<byte>();

        for (int i = 1; i <= 255; i++)
        {
            byte[] nByte = BitConverter.GetBytes((byte)i);
            foreach (byte b in nByte)
            {
                byteList.Add(b);
            }
        }

        for (int g = 256; g <= 1000; g++)
        {
            UInt16 st = Convert.ToUInt16(g);
            byte[] xByte = BitConverter.GetBytes(st);
            foreach (byte c in xByte)
            {
                byteList.Add(c);
            }
        }


        byte[] sendMsg = byteList.ToArray();

谢谢你。

4

5 回答 5

6

您需要使用:

BitConverter.GetBytes(INTEGER);
于 2009-07-08T18:12:44.917 回答
3

想想你将如何区分:

260, 1  -> 0x1, 0x4, 0x1
1, 4, 1 -> 0x1, 0x4, 0x1

如果将一个字节用于 255 以内的数字,将两个字节用于 256-1000 的数字,您将无法在另一端计算出哪个数字对应于什么。

如果您只需要按照描述对它们进行编码而不用担心它们是如何被解码的,那么这对我来说就像是一个人为的家庭作业或测试,我不愿意为您解决它。

于 2009-07-08T18:47:21.557 回答
2

我认为您正在寻找类似于 7 位编码整数的东西:

protected void Write7BitEncodedInt(int value)
{
    uint num = (uint) value;
    while (num >= 0x80)
    {
        this.Write((byte) (num | 0x80));
        num = num >> 7;
    }
    this.Write((byte) num);
}

(取自System.IO.BinaryWriter.Write(String))。

System.IO.BinaryReader类中找到相反的内容,看起来像这样:

protected internal int Read7BitEncodedInt()
{
    byte num3;
    int num = 0;
    int num2 = 0;
    do
    {
        if (num2 == 0x23)
        {
            throw new FormatException(Environment.GetResourceString("Format_Bad7BitInt32"));
        }
        num3 = this.ReadByte();
        num |= (num3 & 0x7f) << num2;
        num2 += 7;
    }
    while ((num3 & 0x80) != 0);
    return num;
}

我希望这不是家庭作业,即使真的闻起来像。

编辑:

好的,所以为您整理一下:

using System;
using System.IO;

namespace EncodedNumbers
{
    class Program
    {
        protected static void Write7BitEncodedInt(BinaryWriter bin, int value)
        {
            uint num = (uint)value;
            while (num >= 0x80)
            {
                bin.Write((byte)(num | 0x80));
                num = num >> 7;
            }
            bin.Write((byte)num);
        }


        static void Main(string[] args)
        {
            MemoryStream ms = new MemoryStream();
            BinaryWriter bin = new BinaryWriter(ms);

            for(int i = 1; i < 1000; i++)
            {
                Write7BitEncodedInt(bin, i);
            }

            byte[] data = ms.ToArray();
            int size = data.Length;
            Console.WriteLine("Total # of Bytes = " + size);

            Console.ReadLine();
        }
    }
}

对于数字 1-1000,我得到的总大小是 1871 字节。顺便说一句,你能简单地说明这是否是家庭作业吗?显然,无论哪种方式,我们仍然会提供帮助。但我们更希望您更加努力地尝试,这样您才能真正为自己学习。

编辑#2:

如果您只想打包它们而忽略解码它们的能力,您可以执行以下操作:

    protected static void WriteMinimumInt(BinaryWriter bin, int value)
    {
        byte[] bytes = BitConverter.GetBytes(value);
        int skip = bytes.Length-1;
        while (bytes[skip] == 0)
        {
            skip--;
        }
        for (int i = 0; i <= skip; i++)
        {
            bin.Write(bytes[i]);
        }
    }

这将忽略任何为零的字节(从 MSB 到 LSB)。所以对于 0-255 它将使用一个字节。正如其他地方所述,这将不允许您将数据解码回来,因为流现在是模棱两可的。附带说明一下,这种方法将其压缩到 1743 字节(而不是使用 7 位编码的 1871 字节)。

于 2009-07-08T18:56:39.243 回答
1

一个字节只能保存 256 个不同的值,因此不能将 255 以上的数字存储在一个字节中。最简单的方法是使用 short,即 16 位。如果您真的需要节省空间,您可以使用 10 位数字并将其打包成一个字节数组(10 位 = 2^10 = 1024 个可能的值)。

于 2009-07-08T18:12:17.820 回答
0

天真地(也未经测试):

List<byte> bytes = new List<byte>();

for (int i = 1; i <= 1000; i++)
{
    byte[] nByte = BitConverter.GetBytes(i);
    foreach(byte b in nByte) bytes.Add(b);
}

byte[] byteStream = bytes.ToArray();

会给你一个字节流,每组4个字节是一个数字[1, 1000]。


您可能想做一些工作,以便 i < 256 占用一个字节,i < 65535 占用两个字节,等等。但是,如果您这样做,您将无法从流中读取值。相反,您将添加长度编码或哨兵位或类似的东西。

我会说,不要。只需使用内置类压缩流,或者使用约定的频率集来启动Huffman 编码实现。

于 2009-07-08T18:25:21.303 回答