在 C# 中创建网络数据包结构/类的最佳方法是什么?

发布于 2024-08-01 22:20:57 字数 1333 浏览 4 评论 0原文

我想知道是否有任何好的指南或书籍可以解释在 C# 中处理网络数据包通信的最佳方法?

现在我正在使用一个结构和一个根据该结构的值生成字节数组的方法。

有没有更简单的方法来做到这一点? 或者甚至是更好的方法?

public struct hotline_transaction
{
        private int transaction_id;
        private short task_number;
        private int error_code;
        private int data_length;
        private int data_length2;

...

        public int Transaction_id
        {
            get
            {
                return IPAddress.HostToNetworkOrder(transaction_id);
            }
            set
            {
                transaction_id = value;
            }
        }

...

        public byte[] GetBytes()
        {
            List<byte> buffer = new List<byte>();
            buffer.Add(0); // reserved
            buffer.Add(0); // request = 0

            buffer.AddRange(BitConverter.GetBytes(Task_number));
            buffer.AddRange(BitConverter.GetBytes(Transaction_id));
            buffer.AddRange(BitConverter.GetBytes(error_code));


            buffer.AddRange(BitConverter.GetBytes(Data_length));

            buffer.AddRange(subBuffer.ToArray());

            return buffer.ToArray(); // return byte array for network sending
        }
}

除此之外,是否有关于将网络数据解析为可用结构/类的最佳实践的良好指南或文章?

I'm wondering if there are any good guides or books that explain the best way to handle network packet communication in C#?

Right now I'm using a structure and a method that generates a byte array based on values of the structure.

Is there a simpler way to do this? Or even a better way?

public struct hotline_transaction
{
        private int transaction_id;
        private short task_number;
        private int error_code;
        private int data_length;
        private int data_length2;

...

        public int Transaction_id
        {
            get
            {
                return IPAddress.HostToNetworkOrder(transaction_id);
            }
            set
            {
                transaction_id = value;
            }
        }

...

        public byte[] GetBytes()
        {
            List<byte> buffer = new List<byte>();
            buffer.Add(0); // reserved
            buffer.Add(0); // request = 0

            buffer.AddRange(BitConverter.GetBytes(Task_number));
            buffer.AddRange(BitConverter.GetBytes(Transaction_id));
            buffer.AddRange(BitConverter.GetBytes(error_code));


            buffer.AddRange(BitConverter.GetBytes(Data_length));

            buffer.AddRange(subBuffer.ToArray());

            return buffer.ToArray(); // return byte array for network sending
        }
}

Beyond that is there a good guide or article on the best practice of parsing network data into usable structures / classes?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

祁梦 2024-08-08 22:20:57

您听说过 Google 协议缓冲区吗?

协议缓冲区是协议缓冲区的名称
使用的二进制序列化格式
Google 获取大部分数据
通讯。 它的设计目的是:

体积小-高效的数据存储
(远小于 xml)便宜
流程 - 在客户端和
独立于服务器平台-便携式
不同编程之间
架构可扩展 - 添加新的
数据到旧消息

Have you heard of google protocol buffers?

protocol buffers is the name of the
binary serialization format used by
Google for much of their data
communications. It is designed to be:

small in size - efficient data storage
(far smaller than xml) cheap to
process - both at the client and
server platform independent - portable
between different programming
architectures extensible - to add new
data to old messages

那请放手 2024-08-08 22:20:57

好吧,我会倾向于使用 Write(Stream),而不是 GetBytes(),以防它很大……但在一般情况下,有用于此的序列化 API...我会提到我自己的,但我认为人们会厌倦听到它。

顺便说一句,在我看来,hotline_transaction 看起来更像是一个class(而不是struct)。

Well, rather than GetBytes(), I'd be tempted to use a Write(Stream), in case it is big... but in the general case there are serialization APIs for this... I'd mention my own, but I think people get bored of hearing it.

IMO, hotline_transaction looks more like a class (than a struct) to me, btw.

木緿 2024-08-08 22:20:57

您可能应该为此使用 BinaryWriter ,而不是返回 byte[],您应该将 BinaryWriter 传递给序列化代码,即,

public void WriteBytes(BinaryWriter writer)
{
    writer.Write((byte)0); // reserved
    writer.Write((byte)0); // request = 0

    writer.Write(Task_number);
    writer.Write(Transaction_id);
    writer.Write(error_code);

    writer.Write(Data_length);

    subBuffer.WriteBytes(writer);
}

您可以轻松地使用 BinaryWriter 包装现有的 Stream。 如果您确实需要以某种方式获取 byte[],您可以使用 MemoryStream 作为后备流,并在需要时调用 ToArray完毕。

You should probably use a BinaryWriter for this, and rather than returning byte[], you should pass a BinaryWriter to the serialization code, i.e.,

public void WriteBytes(BinaryWriter writer)
{
    writer.Write((byte)0); // reserved
    writer.Write((byte)0); // request = 0

    writer.Write(Task_number);
    writer.Write(Transaction_id);
    writer.Write(error_code);

    writer.Write(Data_length);

    subBuffer.WriteBytes(writer);
}

You can easily wrap an existing Stream with a BinaryWriter. If you really need to get a byte[] somehow, you can use a MemoryStream as a backing stream, and call ToArray when you're done.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文