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

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

文章分类

全部博文(104)

文章存档

2018年(1)

2016年(1)

2015年(101)

2014年(1)

我的朋友

分类: C/C++

2015-04-17 17:06:43

这篇文章是在前一篇文章的基础上,添加并实现在点对点传输过程中,设计到位图操作的方法。
同时在 Main 方法中根据新加入的方法写入测试代码,对方法的正确性进行验证。

1. 添加的方法1 

int Bitmap::restore_bitmap ( char *file_path )

功能描述
该方法可以将位图中的数值信息存储到 file_path 指定的路径下面,
文件的命名已经写入到程序中,无需设定。
路径名称后面不要加上 '/' 分隔符。
将位示图存储到文件中的主要作用是为了实现断点续传的功能。

2. 添加的方法2
int Bitmap::get_download_piece_num ()

功能描述
该方法用于统计位图中的bit 数值来统计当前客户端总共下载了
资源文件中的多少个 piece 的数值。在程序中bit = 1 代表的含义便是,
该 bit 对应的文件 piece 已经被下载到本地。
bit = 0 表示对应资源文件的 piece 还没有被下载到本地。

3. 添加的方法3
bool Bitmap::am_i_interested_in_peer ( Bitmap *peer )

功能描述
该方法是用来表示,传入的对等端 peer 上是否有当前客户端没有的文件块(pieces)
如果,对等端 peer 含有当前客户端没有的文件块,那么当前的客户端对该对等端 peer 是感兴趣的,
这种情形方法返回 true ,接下来便会进行点对点(peer)的文件互传(这个方法中并没有实现)

如果,peer 与 当前客户端
  1. 二者含有的资源文件不同,二者是不匹配的
  2. peer 上含有的资源文件块与客户端上含有的资源文件块完全相同
   3. peer 上含有的资源文件块要 < 客户端上的
  4. peer 、当前客户端对象中的某些字段不合法
上述 4 中情形统统返回 false------------> 当前的客户端对对等端 peer 不感兴趣 

代码如下:

// bit_map.h

点击(此处)折叠或打开

  1. #ifndef BIT_MAP_H
  2. #define BIT_MAP_H

  3. #include <vector>

  4. class Bitmap
  5. {
  6. private:
  7.     std::vector<char> bit_field ;
  8.     int byte_length ;
  9.     int bit_length ;
  10. public :
  11.     Bitmap () {}
  12.     Bitmap ( int need_bit_length )
  13.     {
  14.         bit_length = need_bit_length ;
  15.         byte_length = need_bit_length / 8 ;
  16.     
  17.         // i am afriaid we need one more byte
  18.         if ( (need_bit_length%8) != 0 )
  19.          byte_length += 1 ;
  20.         
  21.         for ( int i = 0 ; i < byte_length ; i++ )
  22.         {
  23.             unsigned char v = 0x00 ; //all bit initialized into 0
  24.             bit_field.push_back ( v ) ;
  25.         }
  26.     }

  27.     ~Bitmap ()
  28.     {
  29.         bit_field.clear () ;
  30.     }

  31.     
  32.     int get_bit_map_value ( int index ) ;
  33.     int set_bit_map_value ( int index , int set_value ) ;
  34.     int set_all ( int set_value ) ;
  35.     void print () ;

  36. // add by Aimer 2015/4/17
  37.     int restore_bitmap ( char *file_path) ;

  38. // add by Aimer 2015/4/17
  39.     int get_download_piece_num () ;

  40. // add by Aimer 2015/4/17
  41.     bool am_i_interested_in_peer ( Bitmap *peer ) ;
  42.     
  43. } ;

  44. #endif


// bit_map.cpp

点击(此处)折叠或打开

  1. #include <cstdio>
  2. #include <cstdlib>
  3. #include <iostream>
  4. #include <vector>
  5. #include <sys/types.h>
  6. #include <sys/stat.h>
  7. #include <fcntl.h>


  8. #include <glog/logging.h>

  9. #include "bit_map.h"

  10. #define set_value_one(value,index) value|=(1<<index)
  11. #define set_value_zero(value,index) value&=~(1<<index)


  12. using namespace std ;

  13. int Bitmap::set_all ( int set_value )
  14. {
  15.   char v ;

  16.   // first , we check set_value : this should be either 0 or 1
  17.   if ( set_value != 1 && set_value != 0 )
  18.   {
  19.     LOG(WARNING)<<"[warning] set value should be 0 or 1";
  20.     return -1 ;
  21.   }
  22.   
  23.  // justify set_value = 1 or = 0
  24.     
  25.  if ( set_value == 0 )
  26.  {
  27.     v = 0x00 ;
  28.  }
  29.  
  30.  if ( set_value == 1 )
  31.  {
  32.     v = 0xff ;
  33.  }
  34.  for ( int i = 0 ; i < bit_field.size() ; i++ )
  35.  {
  36.     bit_field[i] = v ;
  37.  }
  38.  
  39.   return 0 ;
  40. }


  41. int Bitmap::get_bit_map_value ( int index )
  42. {
  43.     int pos_byte = index / 8 ;
  44.     int pos_bit = index % 8 ;

  45.     // first check whether index is leagal
  46.     // index increase by bit

  47.     if ( index < 0 || index > bit_length )
  48.     {
  49.     LOG(WARNING)<<"[warning] index not illegal ";
  50.     return -1 ;
  51.     }
  52.       
  53.     if ( (bit_field[pos_byte] >> pos_bit)&1)
  54.     {
  55.     return 1 ;
  56.     }
  57.     
  58.    else
  59.    {
  60.     return 0 ;
  61.    }
  62.   
  63.    return -1 ; // this branch could not be reach
  64. }

  65. int Bitmap::set_bit_map_value ( int index, int set_value )
  66. {
  67.    int pos_byte = index / 8 ;
  68.    int pos_bit = index % 8 ;

  69.    printf ("pos_byte %d pos_bit %d\n", pos_byte , pos_bit) ;

  70.    // index legal testing , incr by bits

  71.    if ( index < 0 || index >bit_length )
  72.    {
  73.     LOG(WARNING)<<"[warning] index illegal range";
  74.     return -1 ;
  75.    }

  76.   // then set_value
  77.    
  78.    if ( set_value != 0 && set_value != 1 )
  79.    {
  80.     LOG(WARNING)<<"[warning] input set_value error ";
  81.     return -1 ;
  82.    }

  83.    char value = bit_field[pos_byte] ;
  84.    // now divide two branches by set_value = 1 or 0
  85.    if ( set_value == 1)
  86.    {
  87.     
  88.     printf ("before %x \n", bit_field[pos_byte]) ;
  89.     // call set_value_one
  90.        set_value_one(value,pos_bit ) ;
  91.         bit_field[pos_byte] = value ;
  92.     printf ("after %x \n",bit_field[pos_byte]) ;
  93.    }
  94.    
  95.    if ( set_value == 0 )
  96.    {
  97.     printf ("before %x \n", bit_field[pos_byte]) ;
  98.     // call set_value_zero
  99.       set_value_zero(value,pos_bit) ;
  100.       bit_field[pos_byte] = value ;
  101.     printf ("after %x \n", bit_field[pos_byte]) ;
  102.    }

  103.   
  104.    return 0 ;
  105. }


  106. void Bitmap::print ()
  107. {
  108.   // this method is used to output each bit in each unsigned char
  109.   // as element stored in each vector<char> bit_field ;
  110.     
  111.   for ( int i = 0 ; i < bit_field.size() ;i++ )
  112.   {
  113.     for ( int j = 0 ; j < 7 ; j++ ) // each unsigned char has 8 bits [0...7]
  114.      {
  115.         if ( (bit_field[i] >> j) &1 )
  116.          printf ("1") ;
  117.         else
  118.          printf ("0") ;
  119.     }
  120.     
  121. //    printf ("\n") ;
  122.  }

  123.  printf ("\n") ;
  124. }


  125. // add by Aimer 2015/4/17
  126. int Bitmap::restore_bitmap ( char *file_path )
  127. {
  128.     int     fd ;
  129.     char     file_name[64] ;
  130.     
  131.     if (file_path==NULL)
  132.     {
  133.         LOG(WARNING)<<"[warning] file_path is empty" ;
  134.         return -1 ;
  135.     }
  136.     
  137.     sprintf (file_name, "%s//bitmap%d.dat" , file_path , bit_length ) ;
  138.     fd = open ( file_name , O_RDWR | O_CREAT | O_TRUNC , 0666 ) ;
  139.     if ( fd < 0 )
  140.     {
  141.         LOG(WARNING)<<"[warning] failed to open file %s "<< file_name ;
  142.         return -1 ;
  143.     }

  144.     for ( int i = 0 ; i < bit_field.size () ;i++ )
  145.     {
  146.         if ((write ( fd , &bit_field[i], 1 ) ) != 1 )
  147.         {
  148.             LOG(WARNING)<<"[warning] failed in writing into file ,error in %d byte "<< i ;
  149.             return -1 ;
  150.         }
  151.     }
  152.     
  153.     close ( fd ) ;
  154.     return 0 ;
  155. }

  156. // add by Aimer 2015/4/17
  157. int Bitmap::get_download_piece_num ()
  158. {
  159.     unsigned char test_char [8] =
  160.     {
  161.         0x80, // 1000 0000
  162.         0x40, // 0100 0000
  163.         0x20, // 0010 0000
  164.         0x10, // 0001 0000
  165.         0x08, // 0000 1000
  166.         0x04, // 0000 0100
  167.         0x02, // 0000 0010
  168.         0x01, // 0000 0001
  169.     } ;
  170.     
  171.     int download_piece_num = 0 ;
  172.     for ( int i = 0 ; i < (byte_length-1); i++ )
  173.     {
  174.         for ( int j = 0 ; j < 8 ; j++ )
  175.         {
  176.             if ( test_char[j] & bit_field[i] )
  177.                 download_piece_num++ ;
  178.         }
  179.     }
  180.     
  181.     // the bit_length % 8 , mod remain bits count
  182.     int limit = (bit_length%8)?(bit_length%8):8 ;

  183.     for ( int j = 0 ; j < limit ; j++ )
  184.         if ( test_char[j] & bit_field[byte_length-1] )
  185.             download_piece_num ++ ;
  186.     
  187.     return download_piece_num ;
  188. }

  189. // add by Aimer 2015/4/17
  190. // this method is used to checkout whether "I" the current Bitmap object
  191. // is interested in the resource pieces (represented by bit in bit_field)
  192. // the peer the paramter (Bitmap*) holds

  193. // if the peer holds the resources "I" don't have , return true

  194. // else return false ,presents "I" have the same of more resource pieces
  195. // the peer take , so "I" am not interested in peer


  196. bool Bitmap::am_i_interested_in_peer ( Bitmap *peer )
  197. {
  198.     unsigned char test_char[8] =
  199.     {0x80 , 0x40 , 0x20 , 0x10 , 0x08 , 0x04 , 0x02 , 0x01 } ;
  200.     unsigned char p_c , i_c ;

  201.     if ( peer == NULL )
  202.     {
  203.         LOG(WARNING)<<" peer is empty" ;
  204.     //    printf ("reason %d \n" , __LINE__ ) ;
  205.         return false ;
  206.     }    

  207.     if ( bit_field.size() == 0 || peer->bit_field.size() == 0 )
  208.     {
  209.         LOG(WARNING)<<"[warning] I and peer one or both of us has a empty bit map" ;
  210.     //     printf ("reason %d \n" , __LINE__ ) ;
  211.         return false ;
  212.     }

  213.     if ((byte_length != peer->byte_length) ||
  214.             (bit_length != bit_length ))
  215.     {
  216.          LOG(WARNING)<<"[warning] I and peer valid bit length do not match" ;
  217.     //     printf ("reason %d \n" , __LINE__ ) ;
  218.         return false ;
  219.     }


  220.     
  221.     for ( int i = 0 ; i < ( byte_length -1 ); i++ )
  222.     {
  223.      for ( int j = 0 ; j < 8 ; j++ )
  224.      {
  225.         i_c = ( bit_field[i] & test_char[j] ) ;
  226.         p_c = ( peer->bit_field[i] & test_char[j]);
  227.     
  228.         if ( i_c == 0 && p_c > 0 )
  229.         {
  230.             // "I" do not have the resource piece peer has
  231.             // "I" am intrested in peer

  232.             return true ;
  233.         }
  234.      }
  235.     }
  236.     
  237.     
  238.     int limit = (bit_length%8)?(bit_length%8):8 ;

  239.     for ( int j = 0 ; j < limit ; j++ )
  240.     {
  241.         i_c = (bit_field[byte_length-1] & test_char[j] ) ;
  242.         p_c = (bit_field[byte_length-1] & test_char[j]) ;
  243.         
  244.         if ( i_c > 0 && p_c == 0 )
  245.             return true ;
  246.     }
  247.     
  248.     return false ;
  249. }

// Main.cpp

点击(此处)折叠或打开

  1. #include <cstdio>
  2. #include <cstdlib>
  3. #include <iostream>
  4. #include <vector>
  5. #include <glog/logging.h>
  6. #include "bit_map.h"

  7. using namespace std ;

  8. int main ( int argc , char **argv )
  9. {
  10.     int need_bit_length = 1024 ;

  11.     // initialize log system
  12.     google::InitGoogleLogging( argv[0] ) ;
  13.     // set log path
  14.     FLAGS_log_dir = "./log/" ;
  15.     
  16. // test Bitmap's constructor
  17.     Bitmap bitMap(need_bit_length) ;
  18.  
  19. // test Bitmap's set all
  20.     bitMap.set_all( 1 ) ;
  21.     
  22. // test Bitmap's print
  23.     bitMap.print () ;
  24.   
  25.     int index = 5 ;
  26.    
  27. // test Bitmap's set_bit_map_value
  28.     bitMap.set_bit_map_value ( index , 0 ) ;

  29.     bitMap.print () ;
  30.     
  31. // test Bitmap's get_bit_map_value
  32.    
  33.     int result = bitMap.get_bit_map_value ( index ) ;
  34.     // it must should be 0
  35.    
  36.     printf (" get value = %d \n",result ) ;

  37. // test Bitmap's restore_bitmap
  38.    char file_path [64] ;
  39.    
  40.    printf ("input file path to store bitmap content into file \n") ;
  41.    scanf ("%s" , file_path) ;
  42.     bitMap.restore_bitmap ( file_path ) ;


  43. // test Bitmap's get_download_piece_num
  44.     int download_counter =
  45.         bitMap.get_download_piece_num () ;
  46. // 1023 should be the right result
  47.        printf ("download_piece_num : %d \n" , download_counter ) ;
  48.     

  49. // test Bitmap's am_i_interested_in_peer
  50.     Bitmap peer_bitMap ( 1024 ) ;
  51.     peer_bitMap.set_all (1) ;
  52.     
  53.         if ( bitMap.am_i_interested_in_peer ( &peer_bitMap ) )
  54.     {
  55.         printf ("I am interested in peer's resource pieces \n") ;
  56.     }
  57.     else
  58.     {
  59.         printf ("I am not interested in peer's reousrce pieces \n") ;
  60.     }

  61.     return 0 ;
  62. }

end

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

夏目玲子2015-04-17 17:07:33

没错! Aimer 就是我!