- 1、本文档共31页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
第五章 发送和接收数据 目标 掌握本机字节顺序以及网络字节顺序的区别 掌握C语言对齐规则以及由此导致的问题 掌握消息成帧的两种方式:文本字符格式和数据结构体方式。 掌握案例:一个简单的投票系统 概述 任何交换信息的程序都必须就如何编码信息(表示为一个位序列)达成一致,即发送信息是以何种格式,接收者必须以同样的信息格式进行解析。这种关于通过通信信道交换的信息的形式和含义的协定称为协议(protocol)。 大多数应用程序协议是依据由字段(field)序列构成的具体消息定义的。每个字段都包含一份特定的编码为位序列的信息。应用程序协议准确指定了发送者如何排列这些序列,以及接收者如何解释或解析它们。 自定义协议和标准协议。 整数的大小(1) 在某种意义上,所有类型的信息最终都将被编码为固定大小的整数。 C语言定义的几种整型:char short int long C语言没有指定这些整型的存储位数的准确大小,而是把它留给实现来完成。因此整型存储位数大小可能因平台而异。 计算整型存储位数的大小是:sizeof,以字节为单位,例如: sizeof(int)。 整数的大小(2) 通过TCP连接发送32位整数,在不同的平台上可能存在不同的解释,可以解释为int,也可以解释为long。 C99语言标准规范以一组可选类型的形式提供了一种解决方案:int8_t int16_t int32_t int64_t。这样可以有效地解决整数存储位数不一致的问题。 c99 c99是在c89的基础上发展起来的,增加了基本数据类型,关键字和一些系统函数等。其实在初学阶段C89(ANSI C)和C99的区别是不易察觉的,所以不必太在意这个。 C99有一部分是对于大字符集的优化,还加入了一些数据库函数,是C89之后的标准,我们用的C是C89标准的,C++是C89编写的,目前的C99标准其实在以前的编译器中就或多或少的支持了,目前完全支持的有这些:GCC、Borland C++等。 字节排序(1) 对于需要多个字节进行编码的整数,必须回答以哪种顺序发送字节的问题。 例如:123456787654321L的十六机制为0x0000704885F926B1 字节排序(2) 网络字节顺序:使用大端字节顺序 本机字节顺序:可能是大端也可能是小端顺序存储。 本机字节顺序与网络字节顺序之间转换函数:htons htonl ntohs ntohl 符号性与符号扩展 负数在C语言中采用补码表示。 负数值赋给无符号的变量时将使负数的符号位变量值的一部分。 在计算表达式的值时,首先要将变量的值加宽到本机(int)大小。例如 char a, b ; sizeof(a+b) 的值为4 手工编码整数 程序BruteForceCoding.c中的EncodeIntBigEndian使用大端表示法把任何给定的基本整数值作为指定字节数的序列存放在内存中的指定位置。 DecodeIntBigEndian方法用于处理将给定长度的字节序列解码为64位的整数,并将其解释为大端序列。 BruteForceCoding.c 在流中包装TCP套接字(1) 编码多个字节的整数可以使用流的方式在TCP套接字上传输。 FILE工具流:通过fdopen()调用把一个或多个FILE流与套接字描述符相关联。 FILE *fdopen(int socketdes, const char *mode); int fclose(FILE *stream); int fflush(FILE *stream); frwrite(….) fread(…) 在流中包装TCP套接字(2) 结构覆盖:对齐与填充(1) 构造包含二进制数据(即多字节整数)的消息的最常用的方法是把C结构覆盖在一块内存区域上,并直接分配给结构的字段。 例如地址信息结构如下: struct addressInfo { uint16_t streetAddress; //街道编号 int16_t aptNumber; //公寓编号 uint32_t postalCode; //邮编 } addrInfo; 结构覆盖:对齐与填充(2) 发送结构体信息 (假设结构体已经赋值) addrInfo.streetAddress = htons( addrInfo.streetAddress ) addrInfo.aptNumber = htons( addrInfo. aptNumber ) addrInfo.postalCode = htonl( addrInfo. postalCode ) if(send(sock, addrinfo, sizeof(addrinf
文档评论(0)