SOCKET通信中结构体中变长字符串处理的问题

合集下载

socket异常解决方案

socket异常解决方案

socket异常解决方案
《Socket异常解决方案》
在开发网络应用程序时,我们经常会遇到socket异常的问题。

socket异常可能会导致网络连接失败,数据传输中断,甚至导
致程序崩溃。

在面对这些问题时,我们需要及时解决并找出根本原因。

首先,我们需要了解造成socket异常的可能原因。

常见的原
因包括网络连接问题,服务器故障,数据包丢失等。

在了解了可能的原因后,就需要针对性地解决这些问题。

解决socket异常的方案可能包括以下几点:
1. 检查网络连接:确认网络连接是否正常,尝试其他网络环境,比如切换到4G网络或者使用VPN连接。

如果网络连接出现
问题,可能是导致socket异常的原因之一。

2. 重启服务器:如果是服务器端出现了问题,可以尝试重启服务器或者联系服务器管理员进行排查。

3. 检查数据包:数据包丢失可能会导致socket异常,对于这
种情况,我们可以使用数据包监控工具来检查数据传输情况,找出问题所在。

4. 异常处理:在程序中加入异常处理机制是很重要的,比如捕获socket异常并进行相应的处理,比如重新连接,重传数据
等。

5. 更新软件版本:有时socket异常可能是由于软件版本过低或者存在bug所致,及时更新软件版本可能解决这些问题。

总之,解决socket异常需要综合考虑网络环境、服务器端和客户端的问题,及时采取合理的措施来解决和避免出现异常情况。

希望上述的解决方案能帮助大家更好地解决socket异常的问题。

socket编程——sockaddr_in结构体操作

socket编程——sockaddr_in结构体操作

socket编程——sockaddr_in结构体操作sockaddr结构体sockaddr的缺陷: struct sockaddr 是⼀个通⽤地址结构,这是为了统⼀地址结构的表⽰⽅法,统⼀接⼝函数,使不同的地址结构可以被bind() , connect() 等函数调⽤;sa_data把⽬标地址和端⼝信息混在⼀起了struct sockaddr {unsigned short sa_family; char sa_data[14]; };sa_family是通信类型,最常⽤的值是 "AF_INET"sa_data14字节,包含套接字中的⽬标地址和端⼝信息sockaddr_in 结构体:struct sockaddr_in中的in 表⽰internet,就是⽹络地址,这只是我们⽐较常⽤的地址结构,属于AF_INET地址族,他⾮常的常⽤sockaddr_in结构体解决了sockaddr的缺陷,把port和addr 分开储存在两个变量中struct sockaddr_in { short int sin_family; unsigned short int sin_port;struct in_addr sin_addr;struct in_addr {unsigned long s_addr;}unsigned char sin_zero[8];}sin_port和sin_addr都必须是NBO⼀般可视化的数字都是HBO(本机字节顺序)sin_zero 初始值应该使⽤函数 bzero() 来全部置零。

⼀般采⽤下⾯语句struct sockaddr_in cliaddr;bzero(&cliaddr,sizeof(cliaddr));sockaddr_in结构体变量的基本配置struct sockaddr_in ina;bzero(&ina,sizeof(ina));ina.sin_family=AF_INET;ina.sin_port=htons(23);ina.sin_addr.s_addr = inet_addr("132.241.5.10");sockaddr 和 sockaddr_in的相互关系⼀般先把sockaddr_in变量赋值后,强制类型转换后传⼊⽤sockaddr做参数的函数sockaddr_in⽤于socket定义和赋值sockaddr⽤于函数参数最典型的源、⽬的节点socket定义对于源、⽬的地址和源、⽬的地址端⼝,需要建⽴两个socket变量cliaddr绑定源地址和源端⼝servaddr⽤于connect和sendto的设定⽬的地址和⽬的端⼝struct sockaddr_in servaddr,cliaddr;create_socket(char *server_addr_string,unsigned int server_port){源socket赋值bzero(&cliaddr,sizeof(cliaddr));cliaddr.sin_family = AF_INET;通常TCP/UDP 协议源地址和端⼝都是随机的cliaddr.sin_addr.s_addr = htons(INADDR_ANY);cliaddr.sin_port = htons(0);⽬的socket赋值bzero(&servaddr,sizeof(servaddr));servaddr.sin_family = AF_INET;inet_aton(server_addr_string,&servaddr.sin_addr);servaddr.sin_port = htons(server_port);}⽹络字节顺序 (Network Byte Order) NBO结构体的sin_port和sin_addr都必须是NBO本机字节顺序 (Host Byte Order) HBO⼀般可视化的数字都是HBONBO,HBO⼆者转换inet_addr() 将字符串点数格式地址转化成⽆符号长整型(unsigned long s_addr s_addr;)inet_aton() 将字符串点数格式地址转化成NBOinet_ntoa () 将NBO地址转化成字符串点数格式htons() "Host to Network Short"htonl() "Host to Network Long"ntohs() "Network to Host Short"ntohl() "Network to Host Long"常⽤的是htons(),inet_addr()正好对应结构体的端⼝类型和地址类型三种给socket赋值地址的⽅法inet_aton(server_addr_string,&myaddr.sin_addr);myaddr.sin_addr.s_addr = inet_addr("132.241.5.10");INADDR_ANY转不转NBO随便myaddr.sin_addr.s_addr = htons(INADDR_ANY);myaddr.sin_addr.s_addr = INADDR_ANY;两种给socket 赋值端⼝的⽅法#define MYPORT 3490myaddr.sin_port = htons(MYPORT);0(随机端⼝)转不转NBO随便myaddr.sin_port = htons(0);myaddr.sin_port = 0;htons/l和ntohs/l等数字转换都不能⽤于地址转换,因为地址都是点数格式,所以地址只能采⽤数字/字符串转换如inet_aton,inet_ntoa;唯⼀可以⽤于地址转换的htons是针对INADDR_ANYcliaddr.sin_addr.s_addr = htons(INADDR_ANY)inet_addr()与inet_aton()的区别inet_addr() 是返回值型struct sockaddr_in ina;ina.sin_addr.s_addr = inet_addr("132.241.5.10");inet_aton() 是参数指针型struct sockaddr_in ina;inet_aton("132.241.5.10",&ina.sin_addr);inet_ntoa 将NBO地址转化成字符串点数格式参数:结构体变量.sinaddr返回值:字符串指针a1 = inet_ntoa(ina.sin_addr);printf("address 1: %s\n",a1);address 1: 132.241.5.10inet_addr()的缺陷:必须对-1做检测处理因为inet_addr()的结果是整型,⽽发⽣错误时返回-1。

c语言字符串的简单处理

c语言字符串的简单处理

c语言字符串的简单处理C语言字符串的简单处理在C语言中,字符串是一种常见的数据类型,用于存储字符序列。

在程序中,我们经常需要对字符串进行一些简单的处理,例如字符串的拼接、查找特定字符、计算字符串的长度等操作。

本文将介绍一些常用的字符串处理方法,帮助读者更好地理解和应用C语言中的字符串操作。

一、字符串的定义和初始化在C语言中,字符串是由字符组成的字符数组。

我们可以通过以下两种方式来定义和初始化字符串:1. 使用字符数组方式定义和初始化字符串:char str1[] = "Hello World";2. 使用指针方式定义和初始化字符串:char *str2 = "Hello World";二、字符串的输出和输入在C语言中,我们可以使用printf函数来输出字符串,使用scanf 函数来输入字符串。

1. 输出字符串:printf("%s\n", str1);2. 输入字符串:scanf("%s", str1);需要注意的是,在使用scanf函数输入字符串时,需要保证输入的字符串长度不超过定义的字符数组长度,否则会发生溢出错误。

三、字符串的拼接在C语言中,我们可以使用strcat函数来实现字符串的拼接。

1. 使用strcat函数拼接字符串:char str3[20] = "Hello";char str4[] = "World";strcat(str3, str4);printf("%s\n", str3); // 输出结果为"HelloWorld"需要注意的是,在使用strcat函数拼接字符串时,需要保证目标字符数组长度足够大,以避免发生溢出错误。

四、字符串的复制在C语言中,我们可以使用strcpy函数来实现字符串的复制。

1. 使用strcpy函数复制字符串:char str5[20];char str6[] = "Hello World";strcpy(str5, str6);printf("%s\n", str5); // 输出结果为"Hello World"需要注意的是,在使用strcpy函数复制字符串时,需要保证目标字符数组长度足够大,以避免发生溢出错误。

常量字符串过长的解决办法

常量字符串过长的解决办法

常量字符串过长的解决办法随着软件行业的飞速发展,对于软件系统的要求也越来越高。

如果某个软件系统中经常使用常量字符串,而这些字符串非常长,经常会出现这样的问题:这些常量字符串很长,会引起编码冲突,增加系统复杂度,减少软件系统的运行效率,从而引发软件运行缓慢或出错等问题。

因此,对于常量字符串过长的情况,如何有效的解决办法,成为许多软件行业从业者和工程师们需要解决的问题。

首先,要想有效解决常量字符串过长的问题,应从代码编写的角度入手,从多方面综合考虑,尽量简洁地编写代码,减少字符串的使用,如果可以,可以考虑将某些字符串分割成多个子字符串,减少字符串的长度,从而有效的减少编码冲突,提高软件系统的运行效率。

其次,要有效解决常量字符串过长的问题,还可以应用新的编程技术。

比如:采用正则表达式,通过正则表达式对字符串进行分析、分割和匹配,这样做可以有效的减少字符串的长度,从而降低编码冲突,同时提高软件系统的运行效率。

此外,为了有效的解决常量字符串过长的问题,要使用相应的开发工具,比如:IDE(Integrated Development Environment)集成开发环境,可以通过设置代码检查和字符串长度限制,有效的限制字符串的长度,从而解决常量字符串过长的问题。

最后,要有效的解决常量字符串过长的问题,应建立文档管理系统,将字符串管理成一个可以查询的数据库,这样做可以有效的减少字符串的长度,从而节约编码时间,提高软件系统的运行效率,同时也可以节约系统资源,提高软件系统的运行速度。

综上所述,要有效的解决常量字符串过长的问题,可以采取代码编写、采用正则表达式、IDE软件、文档管理系统等多种方式,从多个角度综合考虑,充分考虑到实际情况,根据不同情况,采取有效的解决办法。

最后,常量字符串过长的解决办法是有效的,但不能一刀切,一定要根据实际情况,从多个角度进行考虑,采取有效的措施,以保证软件系统的正常运行。

常量字符串过长的解决办法

常量字符串过长的解决办法

常量字符串过长的解决办法在计算机编程中,常量字符串指的是不可变的字符串,它们是在程序的开发过程中的一种重要的工具,其用途广泛,但是如果常量字符串过长,就会带来一系列的问题。

首先,过长的常量字符串可能导致程序变得不清晰,从而导致调试和维护的困难。

无论是进行程序设计还是实现程序,都需要大量的代码,而过长的常量字符串会使代码显得混乱,因此,程序员在调试和维护程序时可能会更容易出错,而在更复杂的情况下,错误可能会严重影响程序的最终效果。

其次,过长的常量字符串会增加程序的内存开销,因为程序需要将其保存在内存中,使用着会消耗一定的系统内存,并且如果过长的字符串反复出现,则系统的内存开销会随之增加。

此外,如果程序中还使用着一些额外的计算,转换和输出操作,过长的常量字符串会显著增加这些操作所需要的时间,从而使程序效率降低或性能下降,甚至出现崩溃等后果。

因此,为了解决常量字符串过长的问题,我们可以采取合理的措施:首先,应该尽量避免使用过长的常量字符串,尽可能缩短字符串的长度。

这样可以减少系统的负载,也有利于程序员的调试和维护工作。

其次,为了缩短字符串的长度,可以考虑使用折行符和引号,以减少程序中字符串的行数。

此外,可以使用动态内存分配来缩短字符串的长度,这样可以有效提高内存利用率。

最后,应该尽量使用变量和函数来替代大量的常量字符串,以提高程序的可读性和维护性。

当程序中出现大量的重复性字符串时,可以采用类似的方法来解决问题,虽然可能会增加一定的编码成本,但在长期的维护过程中可以节省更多的成本。

总而言之,当面对过长的常量字符串时,我们一定要采取行之有效的措施,以节省系统资源,提升程序运行效率,减少调试和维护成本,提高程序的可读性,保证程序的正常运行,从而得到更好的最终效果。

C++中用Socket实现对结构体、长字符串和图片的传输

C++中用Socket实现对结构体、长字符串和图片的传输

C++中用Socket实现对结构体、长字符串和图片的传输C++中用Socket实现对结构体、长字符串和图片的传输首先说明下,本文的Socket传输引用了CBlockingSocket封装类这个类比较特殊的是Send和Receive的最后一个参数是超时时间,其它与C库里的类似首先说结构体吧,这里传输的结构体含有八个整型,如下[cpp]view plaincopyprint?1.typedef struct exceptiontypecount{2.int img_num;3.int ptz_num;4.int preset_num;5.int video_num;6.int device_num;7.int total_num;8.int total_channel;9.int useless;10.}ExceptionCount,*pExceptionCount;关于Socket的创建和连接这里就不说了,参见点击打开链接这里只说下收发部分的实现服务端:[cpp]view plaincopyprint?1.[cpp]view plaincopyprint?1.memset(counttemp,0,256);//清空缓存2.memcpy(counttemp,&ExCount,sizeof(ExCount));//将结构体转为字符串3.int countlen = sockCon.Send(counttemp,256,1000);其中,char countemp[256], ExCount是实例化的结构体。

客户端:[cpp]view plaincopyprint?1. memset(countbuff,0,256);2.int len = sClient.Receive(countbuff,256,1000); // 接受故障数据3.memset( &count,0,sizeof(count));4.memcpy( &count, countbuff, sizeof(count) );这里的count即为输出的结构体,countbuff同样也是个char[256]。

C语言之socket开发TCP、UDP通信总结

C语言之socket开发TCP、UDP通信总结一、什么是socket?Socket的英文原义是“孔”或“插座”。

在编程中,Socket被称做套接字,是网络通信中的一种约定。

Socket编程的应用无处不在,都与Socket 编程有关。

我们平时使用浏览器查资料,这个过程的技术原理是怎样的呢?我们平时使用浏览器,大致就是这样的一个过程。

这里有两个重要的名词:服务端与客户端。

Socket编程的目的就是如何实现这两端之间的通信。

1、Socket编程在嵌入式中也很重要Socket编程不仅仅在互联网方面很重要,在我们的嵌入式方面也是非常的重要,因为现在很多电子设备都趋向于联网。

比如很多嵌入式工作的招聘要求都会有这一条要求:二、Socket编程中的几个重要概念Socket编程用于解决我们客户端与服务端之间通信的问题。

我们平时多多少少都有听过IP地址、端口、TCP协议、UDP协议等概念,这些都与Socket编程中相关,想要知道怎么用起来,当然得先了解它们的一些介绍。

下面看一下这些专业术语的一些要点介绍:1、什么是IP地址?IP地址(InternetProtocolAddress)是指互联网协议地址,又译为网际协议地址。

IP地址被用来给Internet上的电脑一个编号。

我们可以把“个人电脑”比作“一台电话”,那么“IP地址”就相当于“电话号码”。

若计算机1知道计算机2的IP地址,则计算机1就能访问计算机2。

IP地址是一个32位的二进制数,通常被分割为4个“8位二进制数”(也就是4个字节)。

IP地址通常用点分十进制表示成(a.b.c.d)的形式,其中,a,b,c,d都是0~255之间的十进制整数。

例:点分十进IP地址(100.4.5.6),实际上是32位二进制数(01100100.00000100.00000101.00000110)。

IP地址有IPv4与IPv6之分,现在用得较多的是IPv4。

其中,有一个特殊的IP地址需要我们记住:127.0.0.1,这是回送地址,即本地机,一般用来测试使用。

Python中用struct模块处理二进制数据

Python中用struct模块处理二进制数据有的时候需要用python处理二进制数据,比如,存取文件,socket操作时.这时候,可以使用python的struct 模块来完成.可以用struct来处理c语言中的结构体.struct模块中最重要的三个函数是pack(), unpack(), calcsize()pack(fmt, v1, v2, ...) 按照给定的格式(fmt),把数据封装成字符串(实际上是类似于c结构体的字节流)unpack(fmt, string) 按照给定的格式(fmt)解析字节流string,返回解析出来的tuplecalcsize(fmt) 计算给定的格式(fmt)占用多少字节的内存struct中支持的格式如下表:> 格式c类型python类型> x char 无(表示填充字节)> c char 长度为1的字符串> b signed char integer> B unsigned char integer> h short integer> H unsigned short integer> i int integer> I unsigned int long> l long integer> L unsigned long long> q long long l ong> Q u nsigned long long long> f float float> d double float> s char[] string> p char[] string> P void* integer注1.q和Q只在机器支持64位操作时有意思注2.每个格式前可以有一个数字,表示个数注3.s格式表示一定长度的字符串,4s表示长度为4的字符串,但是p表示的是pascal字符串注4.P用来转换一个指针,其长度和机器字长相关默认情况下struct根据本地机器字节顺序转换.不过可以用格式中的第一个字符来改变对齐方式.定义如下:> 字符字节顺序长度和对齐方式> @ native native> = n ative standard> < l ittle-endian standard> > b ig-endian standard> ! network (= big-endian) standard有了struct,我们就可以很容易操作二进制数据了.比如有一个结构体:struct Header{unsigned short id;char[4] tag;unsigned int version;unsigned int count;}通过socket.recv接收到了一个上面的结构体数据,存在字符串s中,现在需要把它解析出来,可以使用unpack()函数.import structid, tag, version, count = struct.unpack("!H4s2I", s)上面的格式字符串中,!表示我们要使用网络字节顺序解析,因为我们的数据是从网络中接收到的,在网络上传送的时候它是网络字节顺序的.后面的H表示一个unsigned short的id,4s表示4字节长的字符串,2I表示有两个unsigned int类型的数据.就通过一个unpack,现在id, tag, version, count里已经保存好我们的信息了.同样,也可以很方便的把本地数据再pack成struct格式.ss = struct.pack("!H4s2I", id, tag, version, count);pack函数就把id, tag, version, count按照指定的格式转换成了结构体Header,ss现在是一个字符串(实际上是类似于c结构体的字节流),可以通过socket.send(ss)把这个字符串发送出去.。

Pythonstruct详解

Pythonstruct详解最近在学习python⽹络编程这⼀块,在写简单的socket通信代码时,遇到了struct这个模块的使⽤,当时不太清楚这到底有和作⽤,后来查阅了相关资料⼤概了解了,在这⾥做⼀下简单的总结。

了解c语⾔的⼈,⼀定会知道struct结构体在c语⾔中的作⽤,它定义了⼀种结构,⾥⾯包含不同类型的数据(int,char,bool等等),⽅便对某⼀结构对象进⾏处理。

⽽在⽹络通信当中,⼤多传递的数据是以⼆进制流(binary data)存在的。

当传递字符串时,不必担⼼太多的问题,⽽当传递诸如int、char之类的基本数据的时候,就需要有⼀种机制将某些特定的结构体类型打包成⼆进制流的字符串然后再⽹络传输,⽽接收端也应该可以通过某种机制进⾏解包还原出原始的结构体数据。

python中的struct模块就提供了这样的机制,该模块的主要作⽤就是对python基本类型值与⽤python字符串格式表⽰的C struct类型间的转化(This module performs conversions between Python values and C structs represented as Python strings.)。

stuct模块提供了很简单的⼏个函数,下⾯写⼏个例⼦。

1、基本的pack和unpackstruct提供⽤format specifier⽅式对数据进⾏打包和解包(Packing and Unpacking)。

例如:import structimport binasciivalues = (1, 'abc', 2.7)s = struct.Struct('I3sf')packed_data = s.pack(*values)unpacked_data = s.unpack(packed_data)print 'Original values:', valuesprint 'Format string :', s.formatprint 'Uses :', s.size, 'bytes'print 'Packed Value :', binascii.hexlify(packed_data)print 'Unpacked Type :', type(unpacked_data), ' Value:', unpacked_data输出:Original values: (1, 'abc', 2.7)Format string : I3sfUses : 12 bytesPacked Value : 0100000061626300cdcc2c40Unpacked Type : <type 'tuple'> Value: (1, 'abc', 2.700000047683716)代码中,⾸先定义了⼀个元组数据,包含int、string、float三种数据类型,然后定义了struct对象,并制定了format‘I3sf’,I 表⽰int,3s表⽰三个字符长度的字符串,f 表⽰ float。

从字符串中找出最长子字符串的方法

从字符串中找出最长子字符串的方法在编程中,字符串操作是一项常见的任务。

找出最长子字符串是字符串处理中的一个特定问题,它在多种应用场景中都有涉及。

本文将详细介绍一种方法来找出给定字符串中的最长子字符串。

### 方法概述在讨论具体方法之前,我们先明确一下概念。

最长子字符串是指在给定字符串中,长度最长的连续字符序列,它可以是原字符串的任意部分,但不包含分隔符或额外的空格。

下面是一种常见的算法思路,用于找出最长子字符串:1.**初始化**:设置两个指针,起始位置分别为0,用来标记子字符串的起始和结束位置。

2.**遍历**:移动结束位置的指针,逐个字符检查,记录下当前最长子字符串的信息。

3.**比较和更新**:每移动一次结束指针,就计算当前子字符串的长度,并与之前记录的最长子字符串长度进行比较,如果更长,则更新记录。

4.**重复**:重复步骤2和3,直到结束位置的指针达到字符串末尾。

### 具体实现以下是使用伪代码来描述这一过程:```pseudofunction findLongestSubstring(str):maxLength = 0start = 0end = 0longestSub = ""while end < length(str):# 如果遇到重复字符,移动start指针if str[end] in str[start:end]:start = start + str[start:end].indexOf(str[end]) + 1 # 更新最长子字符串if end - start + 1 > maxLength:maxLength = end - start + 1longestSub = str[start:end+1]end = end + 1return longestSub```### 代码解释- `maxLength`:记录当前最长的子字符串长度。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

SOCKET通信中结构体中变长字符串处理的问题对方的SERVER要求发送规定的结构体数据给它,而结构体中包含有不定长的字符串数据,以空字符表示字符串的结束. 如: 字段名字节数属性描叙...Msg_Length 1 Integer 消息长度Msg_Content Msg_Length 变长字符串消息的内容....小弟,想用char *来表示结构体中的变长字符串,但使用类似:SendDataBuf = (char *)(&CMPP_Connect);ret = send(SocketID,SendDataBuf,MsgLength,0);的语句发送数据的时候,SERVER收到的结构体中变长字符串是字符串指针的地址,没有将实际的内容传递出去,不知道如何解决此问题?2.还有不定长的byte类型,不定长的Block(数据块)类型,怎么定义声明??传一个buf数组,同时带上他的长度就可以把你说的第一个问题,传数组和传指针没有本质的区别啊,检查,算字符串长度的时候,最后一个空字符有没有加进去。

结构体中定义个指针是无法发送出去的,结构体所在的内存和指针指向的内存之间没有什么关系。

所以只能在结构体中定义数组,注意不要定义的太大。

自定义协议发送不定长数据,一般是客户端和服务器约定前面4个字节是个整型,表示后面缓冲区的大小,所以首先取得4个字节,转换为本地字节序,然后按照整型解析就知道后面有多少数据了,问题是TCP包不会一次发送完成,可能会分成几次发送。

消息码+包长+包体,没能理解题意LZ的问题有21:是用send函数发送消息没有发送成功,这个可以通过errno来看,毕竟sokeet errno解释还是比较的情况2:许多报文的编码格式是基于TLV的,这个在SNMP里面体现的很好,SNMP里面私有保文格式千奇百怪。

还有中方式可以参考DNS报文关于域名字符串编码[字符个数]字符串[..]..[0]example:3www5baidu3com0/////////// 序列化//////////////////class ByteBuffer{private:UINT8* base;size_t pos;//位置size_t cap;//容量public:ByteBuffer(size_t capacity):pos(0), cap(capacity) {base = new UINT8[cap];memset(base, 0, cap);}virtual ~ByteBuffer(){delete [] base;base = NULL;}inline UINT8* data() const { return base; }inline size_t position() const { return pos; }//////串行化,将各类型数据组成字符串。

大端对齐。

//////void appendByte(UINT8 value){base[pos++] = value;}void appendWord(UINT16 value){base[pos++] = (UINT8)(value >> 8);base[pos++] = (UINT8)(value & 0xFF);}void appendInt(UINT32 value){base[pos++] = (UINT8)(value >> 24);base[pos++] = (UINT8)((value >> 16) & 0xFF);base[pos++] = (UINT8)((value >> 8) & 0xFF);base[pos++] = (UINT8)(value & 0xFF);}/*基本类型中还有string字符串和byte[]数组,GMT类型。

比如我定义:UINT8 SCNode[4];//SC节点标识码。

Block 4--------------byte[]数组UINT8 SCName[32];//车站(英文)名称。

string 32-----32字节字符串string TextASCII;//文本消息----------------------------未知长度string字符串GMT,Long类型的数,用于表示北京时间,数值上等于从北京时间1970年1月1日0时起,到所要表示时刻所经过的秒数)//不知道怎么表示??*/// void appendDateTime(DATE, UINT8[4],value)// {// base[pos++] = (UINT8)(value >> 24);// base[pos++] = (UINT8)((value >> 16) & 0xFF);// base[pos++] = (UINT8)((value >> 8) & 0xFF);// base[pos++] = (UINT8)(value & 0xFF);// }// void appendString(char * pStr)// char * p = pStr;// while(*p!=NULL)// {// base[pos++] = (UINT8)(*p);// p++;// }// base[pos++] = 0;// }//// void appendIntArray(int * pData, int len)// {// int * p = pData;// int i = 0;// while(i < len)// {// appendInt((UINT32)*p++);// }// }private:ByteBuffer(const ByteBuffer&);ByteBuffer& operator=(const ByteBuffer&);};/////////////////////*消息构造+序列化*///////////////////////////class MsgStream{public:WORD PLen;//2字节包长度(不包括长度本身)struct PSynMsg{//同步头,来自或发给终端设备的消息无同步字段。

UINT8 SynLen; //1字节(Byte类型)。

同步信息长度(不包括长度本身)UINT8 SynMsg[255];//0-255字节同步信息。

}PSynmsg;//包头。

struct PMsgHead{UINT16 MsgType; //2字节消息分类码UINT32 SendTag; //4字节发送方标识,由发送方分配,唯一标识本会话的流水号。

DWORD DialogSer; //4字节会话流水号UINT16 PSerial; //2字节包序列号,0-65535,按包序递增。

无长度可变部分的包,填0。

UINT8 PackFlag; //1字节标识(Bit1:0请求/1应答,Bit0:0未完/1已完。

)UINT16 LoggerNum;//2字节记录数0-65535UINT8 AlgFlag; //1字节标识(Bit7-4:压缩算法,Bit3-0:加密算法。

)}PMsghead,*phead;//包体,动态顺序串。

typedef struct PMsg{UINT8 *p;//存储空间基地址UINT16 PMsgLen;//串的有效长度}Pmsg;//动态顺序串的类型名//消息认证码MAC(Message Authentication Code)UINT8 MAC[16]; //16字节(BLock类型)///////////////////*序列化消息报文*///////////////////////////void serialize(ByteBuffer& bb){bb.appendWord(PLen); //包长度。

//同步消息。

bb.appendByte(PSynmsg.SynLen); //同步信息长度。

// bb.appendByte(PSynmsg.SynMsg);//0~255字节。

//消息包头。

bb.appendWord(PMsghead.MsgType); //2字节(Word类型)bb.appendInt(PMsghead.SendTag); //4字节(BLock类型)bb.appendInt(PMsghead.DialogSer); //4字节(Long类型)bb.appendWord(PMsghead.PSerial); //2字节(Word类型)bb.appendByte(PMsghead.PackFlag); //1字节(Byte类型)bb.appendWord(PMsghead.LoggerNum);//2字节(Word类型)bb.appendByte(PMsghead.AlgFlag); //1字节(Byte类型)//消息包体序列化???????//16字节的MACfor (int i=0;i<16,i++;){bb.appendByte(MAC[i]);//16 (BLock)}}};/*/////////测试——仅选用:SOC发送给触屏TVM的关闭命令///////////*/ void main(){MsgStream msg;//msg.PLen = sizeof(???)+32;//消息包的长度msg.PSynmsg.SynLen = 0; //同步消息的长度memset(msg.PSynmsg.SynMsg,0,32);//同步消息为空//消息包头的填充msg.PMsghead.MsgType = 0x3000;//3000h-命令类型msg.PMsghead.SendTag = 0x11; //发送方SOC,11hmsg.PMsghead.DialogSer = 0; //流水号0msg.PMsghead.PSerial = 0; //包序列0msg.PMsghead.PackFlag = 0; //1-是最后一包,0-是请求消息:1000 0000 msg.PMsghead.LoggerNum = 0; //命令请求为定长,无记录数为0 msg.PMsghead.AlgFlag = 0; //不加密,不压缩//包体填充:SOC发送给触屏TVM的关闭命令////MAC(Message Authentication Code)memset (msg.MAC,0,16);//清零,16字节的MAC赋值为0。

ByteBuffer bb(1024);//消息报文的序列化,便于Socket网络传输msg.serialize(bb);}问题描述的不清楚,抱歉了。

相关文档
最新文档