优秀的程序设计者这样设计传送的报文

2024-02-08 05:08

本文主要是介绍优秀的程序设计者这样设计传送的报文,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

面对一个人的大型 C/C++程序时,只看其对 struct 的使用情况我们就可以对其编写者的编程经
验进行评估。因为一个大型的 C/C++程序,势必要涉及一些(甚至大量)进行数据组合的结构体,这些结
构体可以将原本意义属于一个整体的数据组合在一起。从某种程度上来说,会不会用 struct,怎样用
struct 是区别一个开发人员是否具备丰富开发经历的标志。 
 在网络协议、通信控制、嵌入式系统的 C/C++编程中,我们经常要传送的不是简单的字节流(char
型数组),而是多种数据组合起来的一个整体,其表现形式是一个结构体。 
 经验不足的开发人员往往将所有需要传送的内容依顺序保存在 char 型数组中,通过指针偏移的
方法传送网络报文等信息。这样做编程复杂,易出错,而且一旦控制方式及通信协议有所变化,程序
就要进行非常细致的修改。 
 一个有经验的开发者则灵活运用结构体,举一个例子,假设网络或控制协议中需要传送三种报
文,其格式分别为 packetA、packetB、packetC: 
struct structA 

 int a; 
 char b; 
}; 
struct structB 

 char a; 
 short b; 
}; 
struct structC 

 int a; 
 char b; 
 float c; 

优秀的程序设计者这样设计传送的报文: 
struct CommuPacket 


 int iPacketType; //报文类型标志 
 union //每次传送的是三种报文中的一种,使用 union 
 { 
 struct structA packetA; struct structB packetB; 
 struct structC packetC; 
 } 
}; 
在进行报文传送时,直接传送 struct CommuPacket 一个整体。 
假设发送函数的原形如下: 
 // pSendData:发送字节流的首地址,iLen:要发送的长度 
Send(char * pSendData, unsigned int iLen); 
发送方可以直接进行如下调用发送 struct CommuPacket 的一个实例 sendCommuPacket: 
Send( (char *)&sendCommuPacket , sizeof(CommuPacket) ); 
假设接收函数的原形如下: 
// pRecvData:发送字节流的首地址,iLen:要接收的长度 
//返回值:实际接收到的字节数 
unsigned int Recv(char * pRecvData, unsigned int iLen); 
接收方可以直接进行如下调用将接收到的数据保存在 struct CommuPacket 的一个实例 recvCommuPacket 中: 
Recv( (char *)&recvCommuPacket , sizeof(CommuPacket) ); 
接着判断报文类型进行相应处理: 
switch(recvCommuPacket. iPacketType) 

case PACKET_A: 
… //A 类报文处理 
break; 
case PACKET_B: 
… //B 类报文处理 
break; 
case PACKET_C: 
… //C 类报文处理 
break; 

以上程序中最值得注意的是 
Send( (char *)&sendCommuPacket , sizeof(CommuPacket) ); 
Recv( (char *)&recvCommuPacket , sizeof(CommuPacket) ); 
中的强制类型转换:(char *)&sendCommuPacket、(char *)&recvCommuPacket,先取地址,再转化为 char 型指针,
这样就可以直接利用处理字节流的函数。 
利用这种强制类型转化,我们还可以方便程序的编写,例如要对 sendCommuPacket 所处内存初始化为 0,可以这
样调用标准库函数 memset(): 
memset((char *)&sendCommuPacket,0, sizeof(CommuPacket)); 
 

这篇关于优秀的程序设计者这样设计传送的报文的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/689982

相关文章

MyBatis设计SQL返回布尔值(Boolean)的常见方法

《MyBatis设计SQL返回布尔值(Boolean)的常见方法》这篇文章主要为大家详细介绍了MyBatis设计SQL返回布尔值(Boolean)的几种常见方法,文中的示例代码讲解详细,感兴趣的小伙伴... 目录方案一:使用COUNT查询存在性(推荐)方案二:条件表达式直接返回布尔方案三:存在性检查(EXI

python编写朋克风格的天气查询程序

《python编写朋克风格的天气查询程序》这篇文章主要为大家详细介绍了一个基于Python的桌面应用程序,使用了tkinter库来创建图形用户界面并通过requests库调用Open-MeteoAPI... 目录工具介绍工具使用说明python脚本内容如何运行脚本工具介绍这个天气查询工具是一个基于 Pyt

Ubuntu设置程序开机自启动的操作步骤

《Ubuntu设置程序开机自启动的操作步骤》在部署程序到边缘端时,我们总希望可以通电即启动我们写好的程序,本篇博客用以记录如何在ubuntu开机执行某条命令或者某个可执行程序,需要的朋友可以参考下... 目录1、概述2、图形界面设置3、设置为Systemd服务1、概述测试环境:Ubuntu22.04 带图

Python程序打包exe,单文件和多文件方式

《Python程序打包exe,单文件和多文件方式》:本文主要介绍Python程序打包exe,单文件和多文件方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录python 脚本打成exe文件安装Pyinstaller准备一个ico图标打包方式一(适用于文件较少的程

Python程序的文件头部声明小结

《Python程序的文件头部声明小结》在Python文件的顶部声明编码通常是必须的,尤其是在处理非ASCII字符时,下面就来介绍一下两种头部文件声明,具有一定的参考价值,感兴趣的可以了解一下... 目录一、# coding=utf-8二、#!/usr/bin/env python三、运行Python程序四、

无法启动此程序因为计算机丢失api-ms-win-core-path-l1-1-0.dll修复方案

《无法启动此程序因为计算机丢失api-ms-win-core-path-l1-1-0.dll修复方案》:本文主要介绍了无法启动此程序,详细内容请阅读本文,希望能对你有所帮助... 在计算机使用过程中,我们经常会遇到一些错误提示,其中之一就是"api-ms-win-core-path-l1-1-0.dll丢失

SpringBoot后端实现小程序微信登录功能实现

《SpringBoot后端实现小程序微信登录功能实现》微信小程序登录是开发者通过微信提供的身份验证机制,获取用户唯一标识(openid)和会话密钥(session_key)的过程,这篇文章给大家介绍S... 目录SpringBoot实现微信小程序登录简介SpringBoot后端实现微信登录SpringBoo

uniapp小程序中实现无缝衔接滚动效果代码示例

《uniapp小程序中实现无缝衔接滚动效果代码示例》:本文主要介绍uniapp小程序中实现无缝衔接滚动效果的相关资料,该方法可以实现滚动内容中字的不同的颜色更改,并且可以根据需要进行艺术化更改和自... 组件滚动通知只能实现简单的滚动效果,不能实现滚动内容中的字进行不同颜色的更改,下面实现一个无缝衔接的滚动

Java使用WebView实现桌面程序的技术指南

《Java使用WebView实现桌面程序的技术指南》在现代软件开发中,许多应用需要在桌面程序中嵌入Web页面,例如,你可能需要在Java桌面应用中嵌入一部分Web前端,或者加载一个HTML5界面以增强... 目录1、简述2、WebView 特点3、搭建 WebView 示例3.1 添加 JavaFX 依赖3

防止SpringBoot程序崩溃的几种方式汇总

《防止SpringBoot程序崩溃的几种方式汇总》本文总结了8种防止SpringBoot程序崩溃的方法,包括全局异常处理、try-catch、断路器、资源限制、监控、优雅停机、健康检查和数据库连接池配... 目录1. 全局异常处理2. 使用 try-catch 捕获异常3. 使用断路器4. 设置最大内存和线