放假归来,半个月没看书了,稍微有些生疏。被安排了新的工作,老的自学任务还需继续完成。
这一章内容比较多,按小节整理了一下。
一、编码整数
1.整数型的大小
由通信过程双方交换信息的协议标准引申出了编码的整数,进而探讨了各个整数类型的大小(char、int、long、int8_t、uint8_t等)、获取它们的长度的方法——sizeof()、并且有一个简单的程序示例TestSizes.c来展示。
2.传输顺序
多个字节编码的整数,是从最高有效位(大端、左端)还是从最低有效位(小端、右端)发送,也是传输双方需要协调的。大多数协议使用大端顺序,因此它也被称为网络字节顺序。
3.符号扩展
利用补码进行符号扩展;不同长度的数据类型复制时的补位。
这一小节使用了一个例子BruteForceCoding.c来展示如何进行移位和掩码操作,相当繁琐。
4.在流中包装套接字
使用fdopen、fclose、fflush。
5.结构填充
优化结构成员的排列顺序可以避免一些不必要的填充。或者,安排额外的结构成员使得其成为可控制的填充部分。
这一部分是一个示例。为了便于复习,把各个组件功能注释一下。与前几章不同的是,这里没有用类似receive()这样的函数,而是采用流的方式进行处理。
VoteClientTCP.c 客户端,用于发送请求。请求有两种,投票和质询。
VoteServerTCP.c 服务器端,接收请求,并根据不同请求,修改或仅查询服务器端数据,并回送。
DelimFramer.c 基于界定符成帧,包含了从流复制字节到缓冲区直到遇到界定符的GetNextMsg( )和根据界定符把缓冲区字节复制到流中的PutMsg( )。
LengthFramer.c 基于长度成帧,包含的两个函数与DelimFramer.c提供的两个函数同名,不同的是它们基于长度成帧。此时消息格式有所不同,按照前面的约定,两个字节的前缀中保存了这个消息的长度。
VoteEncodingText.c 基于文本进行消息编码,包含把序列转化为消息结构的Encode( )和把消息结构转化为字节序列的Decode( )。其中用到的strtok( )第一次分割后,每次分割都要利用NULL作为第一个参数;strtoll( )的用法如下:
longlongint strtoll(constchar*nptr, char**endptr, intbase);
//把nptr按照以base为进制进行转换。endptr非空时把第一个无效字符存放至endptr。参考资料
VoteEncodingBin.c 基于二进制消息编码,包含的两个函数与VoteEncodingText.c提供的两个函数同名,不同的是使用固定大小的消息。
这样,把VoteServerTCP.c、两个成帧模块之一、两个编码模块之一以及辅助模块DieWithMessage.c、TCPClientUtility.c、TCPServerUtility.c和AddressUtility.c一起编译即可获得服务器程序。客户端同理,两者需要使用相同的组合。
p.s.第五章程序尚未测试,由于有其它项目需要进行,暂时搁置TCP/IP Socket编程的学习。
本文转自五岳博客园博客,原文链接:www.cnblogs.com/wuyuegb2312/archive/2011/09/08/2164321.html,如需转载请自行联系原作者