Chinaunix首页 | 论坛 | 博客
  • 博客访问: 562838
  • 博文数量: 104
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1559
  • 用 户 组: 普通用户
  • 注册时间: 2014-08-21 00:58
个人简介

锻炼精神,首先要锻炼肉体

文章分类

全部博文(104)

文章存档

2018年(1)

2016年(1)

2015年(101)

2014年(1)

我的朋友

分类: C/C++

2015-04-24 22:22:15

这篇博文主要是介绍  BitTorrent 中关于对等端收发的不同消息类型的定制,以及消息在网络中的表示方式与主机在接收到消息之后如何解析。

说道消息,无非就是将结构体中的多种不同属性类型字段的变量数值,写入到一个字符串中,这便是消息在发送之前,
从程序到缓冲区,然后再从缓冲区中被打包成数据包,发送到对等端的缓冲区中。
而接收消息的一端,先从缓冲区中会将数据提取到程序缓存变量中(char*, string ...)然后按照双方协定好的协议格式,
来一截一截的抽取指定长度的字节(或是bit),然后再将其转换为不同属性类型字段的变量数值。

而对于消息的处理,可以有如下的几种方法:
1. 直接基于字符串数组的操作 char *, unsigned char * ,这种方法写起来比较麻烦,而且很容易出错
2. 基于一些现有的C++ 标准库中封装的对象,例如使用string , vector 可以节省一部分方法的编写,
    但是空间利用并不好,在将操作细化到 bit 的时候,使用 string 对象类型显然变得没有太多的优势而言
3. 仍旧使用 char * , unsigned char * 作为底层存储数据对象,但是基于其操作的方法使用正则表达式实现,
   这种方法,有很大的优势,因为正则一向是字符串操作的利器,不过我不擅长正则表达式。
4. 使用第三方库来实现,有 MongoDB 中的 BSON, 和 google 中的 protocol buf 或是当下比较流行的 hadoop
    中的 thrift ,或是 hadoop 中的子项目 avro。

我在使用过 1,2,方法之后觉得这种编程方法并不高效,而且看起来也并不具有很好的可读性,所以决定中途放弃这两种方法,
转而使用第 4 个方法。考虑到熟悉程度和库本身的复杂程度,只考虑 BSON 和 protobuf 两种情况

不过在使用方法 4 之前,有几个问题需要思考一下,那便是:
二者之间的区别是什么?
在当前的 BT 项目中哪一个库比较适合?

BSON 是以二进制的方式来表示 JSON 类型,但却并不仅仅是换了一种表达方式,在换了数据表示格式的同时又在
BSON 对象中封装了一些独特的方法。

BSON 比较适用于 shcema-less 的数据传输的封装与解析,而protobuf 比较适用于 shcema 类型数据传输的封装与解析。
打个比方,就是 BSON 更适合传送数据流格式的数据,在数据库之间传输数据表的时候,比较常使用。
而 protobuf 比较适用于传送哈希散列表,键值对这种有固定格式的数据,适合传送字节流格式的数据。

BitTorrent 中需要传输的数据格式可以从 BitTorrent 协议中获知

点击(此处)折叠或打开

  1. enum state          // 当前对等端处于的状态
  2. {
  3.   INITIAL = 0 ,
  4.   HALF_SHAKED,
  5.   HAND_SHAKED,
  6.   SEND_BIT_FIELD,
  7.   RECV_BIT_FIELD,
  8.   EXCHANGING_DATA,
  9.   CLOSING
  10. } ;

  11. const long MSG_LEN = (1024*2 + 1024*16) ;   // 所传输消息的最大长度,单位是字节

  12. typedef struct _request_piece                // 请求文件 piece 的消息
  13. {
  14.   int index ;
  15.   int begin ;
  16.   int length ;
  17. } request_piece_t ;

  18. typedef struct _peer_node                    // 一个对等端上面所包含的所有信息
  19. {
  20.   int socket ;                              // ---> socket 连接套接字描述符
  21.   char ip [16] ;                           //-------> 当前端点的 IP 地址
  22.   unsigned short port ;                    //----> 当前端点的提供服务的端口号
  23.   char id[21] ;                            //----> 不同端点用于唯一标识自己的 id 号码
  24.   
  25.   int state ;                             //-----> 当前下载资源端点所处的状态,由上面的枚举变量 enum state 定义
  26.   
  27.   int am_chocking ;                      //-------> 标识当前端点是否处于“阻塞状态” 也就是不为其他端点提供下载服务的状态
  28.   int am_interested ;                    // 标识当前端点是否对其他端点“感兴趣” 也就是其他端点上有着当前端点没有的资源片段(pieces)
  29.   int peer_chocking ;                    //----------> 对等端是否阻塞,如果对等端阻塞,当前端点将不能从对等端上下载导数据
  30.   int peer_interested ;                 //--对等端是否对当前端点感兴趣,如果感兴趣,说明当前端点上有着对等端上没有的资源片段(pieces)
  31.     
  32.   Bitmap *pBitmap
  33. // 指向一个位图对象,该位图对象整体用于表示一个完整的资源文件,位图中的每一位,唯一索引文件中的一个资源片段(piece)
  34. //位图中的每一位 若为 0 表示端点并不具有该文件片段的资源, 若为 1 说明端点具有该文件的资源,所以其中包含了一个 0,1 组成的字符串序列
  35.   
  36.   std::string buff_in ;                // 存储了当前端点接收来自其他端点的信息,作为接收消息缓冲区使用
  37.  
  38.   std::string msg_out ;               // 作为发送消息缓冲区使用,存储当前端点要发送到其他端点的消息
  39.   
  40.   std::string msg_buff_out ;          // 由于 socket 中的 send 函数一次发送的字符串长度有限,
  41.                                         //所以这个变量做 msg_out 的缓冲区,每次从 msg_oug 中取出固定长度的数据,通过 send 方法发送
  42.   
  43.  // download reqeustes received from others
  44.   std::vector<request_piece_t> recv_download_request_queue ; // 消息请求队列,其中存放了接收来自其余对等端点的请求下载消息
  45. // uploaded requests send to others
  46.   std::vector<request_piece_t> send_upload_request_queue ;  //消息息请求队列,用来存放,当前端点发向对等端点发送的请求下载消息

  47.   unsigned int down_total ;                        // 这些是一些统计信息,用于综合算法的调用
  48.   unsigned int up_total ;

  49.   time_t start_timestamp ;
  50.   time_t recet_timestamp ;
  51.  
  52.   time_t last_down_timestamp ;
  53.   time_t last_up_timestamp ;
  54.  
  55.   uint64_t down_count ;
  56.   uint64_t up_count ;
  57.  
  58.   double down_rate ;
  59.   double up_rate ;


  60. } peer_node_t ;
思维导图如下:



好的,现在回到刚才的问题,BT 项目中的消息传送使用哪一种序列化三方库比较好。
由于消息中多半是流式数据,没有表示层结构体类型的数据类型,所以在这里选择使用 BSON 。


end
阅读(1156) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~