当前位置: 首页 > news >正文

网站建设推进会讲话稿网店网络营销与推广策划书

网站建设推进会讲话稿,网店网络营销与推广策划书,网站与建设的字体间距,济南品牌网站建设价格根据架构设计,实现编解码层的代码设计 Cargo.toml 加入二进制序列化支持 # 序列化支持 ... bincode "1.3" # 添加二进制序列化支持 bytes-utils "0.1" # 添加字节处理工具 开始编码 错误处理(error.rs&#x…

根据架构设计,实现编解码层的代码设计

Cargo.toml 加入二进制序列化支持

# 序列化支持
...
bincode = "1.3"           # 添加二进制序列化支持
bytes-utils = "0.1"       # 添加字节处理工具

开始编码

错误处理(error.rs):

定义了编解码过程中可能遇到的错误类型,使用枚举定义

use thiserror::Error;#[derive(Error, Debug)]
pub enum CodecError {#[error("数据长度不足")]InsufficientData,#[error("校验和错误")]ChecksumMismatch,#[error("无效的起始符")]InvalidStartByte,#[error("无效的命令标识: {0}")] InvalidCommand(u8),#[error("IO错误: {0}")] Io(#[from] std::io::Error),
}

数据帧结构(frame.rs):

- 定义了符合 GBT32960 协议的数据帧结构
- 提供了创建和校验数据帧的方法

frame.rs

use bytes::{ Bytes, BytesMut, BufMut };
use chrono::NaiveDateTime;
use serde::{ Serialize, Deserialize };#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Frame {pub start_byte: u8, // 起始符 0x23pub command_flag: u8, // 命令标识pub response_flag: u8, // 应答标志pub vin: String, // 车辆识别码pub encrypt_method: u8, // 加密方式pub payload_length: u16, // 数据单元长度pub payload: Bytes, // 数据单元pub checksum: u8, // BCC校验码
}impl Frame {pub fn new(command: u8, vin: String, payload: Bytes) -> Self {let payload_length = payload.len() as u16;Self {start_byte: 0x23,command_flag: command,response_flag: 0xfe,vin,encrypt_method: 0x01,payload_length,payload,checksum: 0x00, // 将在编码时计算}}pub fn calculate_checksum(&self) -> u8 {let mut bcc: u8 = 0;// 命令标识bcc ^= self.command_flag;// 应答标志bcc ^= self.response_flag;// VIN码(17位)for byte in self.vin.as_bytes() {bcc ^= byte;}// 加密方式bcc ^= self.encrypt_method;// 数据单元长度(2字节)bcc ^= ((self.payload_length >> 8) & 0xff) as u8;bcc ^= (self.payload_length & 0xff) as u8;// 数据单元for byte in self.payload.iter() {bcc ^= byte;}bcc}
}#[cfg(test)]
mod tests {use super::*;#[test]fn test_calculate_checksum() {let payload = Bytes::from_static(&[0x01, 0x02, 0x03]);let frame = Frame::new(0x01, // command"LSVNV2182E0200001".to_string(), // vinpayload);let checksum = frame.calculate_checksum();assert!(checksum != 0, "校验和不应该为0");// 创建相同内容的帧,校验和应该相同let frame2 = Frame::new(0x01,"LSVNV2182E0200001".to_string(),Bytes::from_static(&[0x01, 0x02, 0x03]));assert_eq!(checksum, frame2.calculate_checksum(), "相同内容的帧应该有相同的校验和");}#[test]fn test_different_content_different_checksum() {let frame1 = Frame::new(0x01, "LSVNV2182E0200001".to_string(), Bytes::from_static(&[0x01]));let frame2 = Frame::new(0x01, "LSVNV2182E0200001".to_string(), Bytes::from_static(&[0x02]));assert_ne!(frame1.calculate_checksum(),frame2.calculate_checksum(),"不同内容的帧应该有不同的校验和");}
}

编解码器(codec.rs):

- 实现了 tokio 的 Decoder 和 Encoder trait
- 负责数据帧的序列化和反序列化

use bytes::{ BytesMut, Buf };
use tokio_util::codec::{ Decoder, Encoder };
use super::{ Frame, CodecError };pub struct Gbt32960Codec;impl Decoder for Gbt32960Codec {type Item = Frame;type Error = CodecError;fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {// 检查数据长度是否足够if src.len() < 22 {// 最小帧长度return Ok(None);}// 检查起始符if src[0] != 0x23 {return Err(CodecError::InvalidStartByte);}// TODO: 实现完整的解码逻辑// 1. 读取各个字段// 2. 验证校验和// 3. 解析数据单元Ok(None)}
}impl Encoder<Frame> for Gbt32960Codec {type Error = CodecError;fn encode(&mut self, frame: Frame, dst: &mut BytesMut) -> Result<(), Self::Error> {// TODO: 实现编码逻辑// 1. 写入各个字段// 2. 计算并写入校验和Ok(())}
}

实现完整的解码逻辑

use bytes::{BytesMut, Buf, BufMut};
use tokio_util::codec::{Decoder, Encoder};
use super::{Frame, CodecError};pub struct Gbt32960Codec;impl Decoder for Gbt32960Codec {type Item = Frame;type Error = CodecError;fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {// 检查数据长度是否足够if src.len() < 22 {  // 最小帧长度return Ok(None);}// 检查起始符if src[0] != 0x23 {return Err(CodecError::InvalidStartByte);}// 读取命令标识和应答标志let command_flag = src[1];let response_flag = src[2];// 读取 VIN 码(17字节)let vin = String::from_utf8_lossy(&src[3..20]).to_string();// 读取加密方式let encrypt_method = src[20];// 读取数据单元长度(2字节)let payload_length = ((src[21] as u16) << 8) | (src[22] as u16);// 检查是否有足够的数据let total_length = 23 + payload_length as usize + 1; // 头部 + 数据单元 + 校验码if src.len() < total_length {return Ok(None);}// 读取数据单元let payload = src.slice(23..23 + payload_length as usize);// 读取校验码let received_checksum = src[total_length - 1];// 创建帧对象进行校验和计算let frame = Frame {start_byte: 0x23,command_flag,response_flag,vin,encrypt_method,payload_length,payload: payload.freeze(),checksum: received_checksum,};// 验证校验和let calculated_checksum = frame.calculate_checksum();if calculated_checksum != received_checksum {return Err(CodecError::ChecksumMismatch);}// 消费已处理的字节src.advance(total_length);Ok(Some(frame))}
}impl Encoder<Frame> for Gbt32960Codec {type Error = CodecError;fn encode(&mut self, frame: Frame, dst: &mut BytesMut) -> Result<(), Self::Error> {// TODO: 实现编码逻辑// 1. 写入各个字段// 2. 计算并写入校验和Ok(())}
}#[cfg(test)]
mod tests {use super::*;use bytes::Bytes;#[test]fn test_decode_valid_frame() {let mut codec = Gbt32960Codec;let mut buffer = BytesMut::new();// 构造测试数据buffer.put_u8(0x23);                          // 起始符buffer.put_u8(0x01);                          // 命令标识buffer.put_u8(0xFE);                          // 应答标志buffer.extend_from_slice(b"LSVNV2182E0200001"); // VIN码buffer.put_u8(0x01);                          // 加密方式buffer.put_u16(2);                            // 数据长度buffer.extend_from_slice(&[0x01, 0x02]);      // 数据单元// 计算并添加校验和let checksum = buffer[1..buffer.len()].iter().fold(0u8, |acc, &x| acc ^ x);buffer.put_u8(checksum);// 解码let result = codec.decode(&mut buffer).unwrap().unwrap();// 验证解码结果assert_eq!(result.command_flag, 0x01);assert_eq!(result.vin, "LSVNV2182E0200001");assert_eq!(result.payload.len(), 2);assert_eq!(buffer.len(), 0); // 确保所有数据都被消费}#[test]fn test_decode_invalid_checksum() {let mut codec = Gbt32960Codec;let mut buffer = BytesMut::new();// 构造测试数据(使用错误的校验和)buffer.put_u8(0x23);buffer.put_u8(0x01);buffer.put_u8(0xFE);buffer.extend_from_slice(b"LSVNV2182E0200001");buffer.put_u8(0x01);buffer.put_u16(0);buffer.put_u8(0xFF); // 错误的校验和// 验证解码失败assert!(matches!(codec.decode(&mut buffer),Err(CodecError::ChecksumMismatch)));}
}

代码地址

阿里云登录 - 欢迎登录阿里云,安全稳定的云计算服务平台

总结

1. 完整的帧解析逻辑:
   - 起始符验证,根据接口协议验证是否0x23开头
   - 命令标识和应答标志解析
   - VIN码解析,vin码17个字节长度
   - 加密方式解析,读取加密方式,测试的时候可以先不使用,上生产环境后要打开
   - 数据单元长度解析,表示数据payload的总长度
   - 数据单元提取
   - 校验和验证
2. 数据完整性检查:
   - 最小帧长度检查
   - 完整数据长度检查
   - 校验和验证
3. 添加了单元测试:
   - 测试有效帧的解码
   - 测试校验和错误的情况

http://www.cadmedia.cn/news/12114.html

相关文章:

  • 免备案的网站建设360搜索推广官网
  • 开发软件下载网站搜一搜
  • 江都建设总部网站福州seo网址优化公司
  • 营销型网站建设的特色百度人工客服电话24小时
  • 白云建设网站seo排名工具有哪些
  • 无锡门户网站制作服务陕西疫情最新消息
  • 福田网站建设龙岗网站建设东莞网站制作模板
  • 个人简历ppt苏州网站优化公司
  • 四川省城乡住房建设部网站网络营销就是
  • 免费企业网站如何建设打开百度一下
  • 注册网站不用手机短信验证的网页制作软件
  • 常州新北建设局网站网站推广及seo方案
  • 外部链接链轮的建设对于网站提google seo 优化招聘
  • 邯郸网站建设信息搜索引擎营销
  • 贵阳网站建设培训学校百度下载应用
  • 如何在网上建立自己的网站私人做网站建设
  • 黄金网站下载免费营销网站模板
  • 成都装修公司一览表seo百度关键字优化
  • 天津关键词优化效果百度seo优化软件
  • 什么是网站后台seo哪家公司好
  • 上海网站建设找缘魁企业网站源码
  • 网站建设文化流程新闻今天
  • 上海网站推广提供商企业邮箱如何申请注册
  • 网站收录查询代码自动点击器怎么用
  • 足球教学网站seo培训一对一
  • 济南网站怎么做搜索引擎优化原理
  • 北京网站建站系统平台windows优化大师是自带的吗
  • 网站建设方案及报价seo技术培训班
  • 公司变更法人一般需要多少时间百度搜索引擎优化方案
  • wordpress上传图片路径修改湘潭seo优化