初学Sockets编程(四) 发送和接收数据

    放假归来,半个月没看书了,稍微有些生疏。被安排了新的工作,老的自学任务还需继续完成。

 

  这一章内容比较多,按小节整理了一下。

 

一、编码整数

1.整数型的大小

  由通信过程双方交换信息的协议标准引申出了编码的整数,进而探讨了各个整数类型的大小(char、int、long、int8_t、uint8_t等)、获取它们的长度的方法——sizeof()、并且有一个简单的程序示例TestSizes.c来展示。

2.传输顺序

  多个字节编码的整数,是从最高有效位(大端、左端)还是从最低有效位(小端、右端)发送,也是传输双方需要协调的。大多数协议使用大端顺序,因此它也被称为网络字节顺序。

3.符号扩展

  利用补码进行符号扩展;不同长度的数据类型复制时的补位。

 

  这一小节使用了一个例子BruteForceCoding.c来展示如何进行移位和掩码操作,相当繁琐。

4.在流中包装套接字

  使用fdopen、fclose、fflush。

5.结构填充

  优化结构成员的排列顺序可以避免一些不必要的填充。或者,安排额外的结构成员使得其成为可控制的填充部分。

6.字符串和文本
  利用wcstombs()和mbstowcs()进行宽字符和适于传输的字符序列之间的转换。
7.位操作
二、构造、成帧和解析消息

  这一部分是一个示例。为了便于复习,把各个组件功能注释一下。与前几章不同的是,这里没有用类似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编程的学习。  

posted @ 2011-09-08 21:37  五岳  阅读(652)  评论(0编辑  收藏  举报
回到顶部