rust- 结构体与二进制数组转换

将结构体当二进制流传输是做网络编程时传输协议的常用功能。golang语言可以使用包 encoding/binary实现,例如


import (
	"encoding/binary"
	"os"
)

...
err := binary.Write(f, binary.LittleEndian, p)
...

rust中可以使用 deku将结构体实例转换为bytes数组。

安装依赖

use anyhow;
use anyhow::bail;
use deku::prelude::*;
use std::net::TcpStream;
use std::{
    io::{Read, Write},
};

定义结构体

#[derive(Debug, PartialEq, DekuRead, DekuWrite, Default)]
struct Message {
    #[deku(endian = "big")]
    msgtype: u32,
    #[deku(endian = "big")]
    taskid: i32,
    #[deku(endian = "big")]
    utctime: u32,
    #[deku(endian = "big", update = "self.data.len()")]
    bodylen: u32,
    #[deku(count = "bodylen", endian = "little")]
    data: Vec<u8>,
}

注意上面的结构体,整数字段有些是使用大段规则,有些是使用小段规则,可以通过如下的宏实现

#[deku(endian = "big")]` 

或

#[deku(endian = "little")]

通常在定义协议时,需要知道协议体的长度,但是协议的body部分通常是可变的,例如data: Vec<u8>,只有在结构体初始化时才知道body的长度,所以这里使用如下宏延迟计算了协议的长度,如下

#[deku(endian = "big", update = "self.data.len()")]
#[deku(count = "bodylen", endian = "little")]

将结构体转换为字节流发送

添加如下宏后

#[derive(Debug, PartialEq, DekuRead, DekuWrite, Default)]

则可以调用 to_bytes()方法进行转换。

将转换后的二进制发送到tcp服务器,如下

impl Message {

    fn send(&self) -> anyhow::Result<()> {
        // 将结构体转换为二进制
        let binary_data = self.to_bytes()?;

        // tcp发送二进制消息
        let mut stream =
            match TcpStream::connect(self.host) {
                Ok(stream) => stream,
                Err(e) => {
                    bail!(
                        "Couldn't connect to server {} {}",
                        self.host,
                        e
                    )
                }
            };
        stream.write_all(&binary_data)?;
        stream.flush()?;

        Ok(())
    }
}

相关推荐

  1. rust- 结构二进制数组转换

    2024-04-01 06:20:05       43 阅读
  2. Rust结构枚举

    2024-04-01 06:20:05       43 阅读
  3. 05 Rust 结构

    2024-04-01 06:20:05       56 阅读
  4. rust结构

    2024-04-01 06:20:05       27 阅读
  5. Rust-07-结构

    2024-04-01 06:20:05       35 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-01 06:20:05       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-01 06:20:05       101 阅读
  3. 在Django里面运行非项目文件

    2024-04-01 06:20:05       82 阅读
  4. Python语言-面向对象

    2024-04-01 06:20:05       91 阅读

热门阅读

  1. rust语言学习入门

    2024-04-01 06:20:05       42 阅读
  2. go、rust去掉了继承

    2024-04-01 06:20:05       36 阅读
  3. OV证书和EV证书的区别

    2024-04-01 06:20:05       36 阅读
  4. os模块篇(五)

    2024-04-01 06:20:05       32 阅读
  5. 算法编程:排列与组合问题

    2024-04-01 06:20:05       38 阅读
  6. HaDoop学习1

    2024-04-01 06:20:05       34 阅读
  7. 华为昇腾认证考试内容有哪些

    2024-04-01 06:20:05       33 阅读
  8. Docker知识简略

    2024-04-01 06:20:05       43 阅读