• bittorrent 学习(四) tracker peer通讯


    看看 tracker.c文件 

    http_encode() 为http发送进行编码转换

     1 int http_encode(unsigned char *in,int len1,char *out,int len2)
     2 {
     3     int  i, j;
     4     char hex_table[16] = "0123456789abcdef"; 
     5     
     6     if( (len1 != 20) || (len2 <= 90) )  return -1;
     7     for(i = 0, j = 0; i < 20; i++, j++) {
     8         if( isalpha(in[i]) || isdigit(in[i]) )
     9             out[j] = in[i];
    10         else { 
    11             out[j] = '%';
    12             j++;
    13             out[j] = hex_table[in[i] >> 4];
    14             j++;
    15             out[j] = hex_table[in[i] & 0xf];
    16         }
    17     }
    18     out[j] = '';
    19     
    20 #ifdef DEBUG
    21     //printf("http encoded:%s
    ",out);
    22 #endif
    23     
    24     return 0;
    25 }
    View Code

    get_tracker_name() 通过截取关键字符 获取网址的名称部分

     1 int get_tracker_name(Announce_list *node,char *name,int len)
     2 {
     3     int i = 0, j = 0;
     4 
     5     if( (len < 64) || (node == NULL) )  return -1;
     6     if( memcmp(node->announce,"http://",7) == 0 ) 
     7         i = i + 7;
     8     while( (node->announce[i] != '/') && (node->announce[i] != ':') ) {
     9         name[j] = node->announce[i];
    10         i++;
    11         j++;
    12         if( i == strlen(node->announce) )  break;
    13     }
    14     name[j] = '';
    15 
    16 #ifdef DEBUG
    17     printf("%s
    ",node->announce);
    18     printf("tracker name:%s
    ",name);
    19 #endif
    20 
    21     return 0;
    22 }
    View Code

    get_tracker_port() 通过截取关键字符 获取端口部分

     1 int get_tracker_port(Announce_list *node,unsigned short *port)
     2 {
     3     int i = 0;
     4 
     5     if( (node == NULL) || (port == NULL) )  return -1;
     6     if( memcmp(node->announce,"http://",7) == 0 )  i = i + 7;
     7     *port = 0;
     8     while( i < strlen(node->announce) ) {
     9         if( node->announce[i] != ':')   { i++; continue; }
    10 
    11         i++;  // skip ':'
    12         while( isdigit(node->announce[i]) ) { 
    13             *port =  *port * 10 + (node->announce[i] - '0');
    14             i++;
    15         }
    16         break;
    17     }
    18     if(*port == 0)  *port = 80;
    19 
    20 #ifdef DEBUG
    21     printf("tracker port:%d
    ",*port);
    22 #endif
    23 
    24     return 0;
    25 }
    View Code

    create_request()创建一个http的请求

     1 int create_request(char *request,int len,Announce_list *node,
     2                    unsigned short port,long long down,long long up,
     3                    long long left,int numwant)
     4 {
     5     char           encoded_info_hash[100];
     6     char           encoded_peer_id[100];
     7     int            key;
     8     char           tracker_name[128];
     9     unsigned short tracker_port;
    10 
    11     http_encode(info_hash,20,encoded_info_hash,100);
    12     http_encode(peer_id,20,encoded_peer_id,100);
    13 
    14     srand(time(NULL));
    15     key = rand() / 10000;
    16 
    17     get_tracker_name(node,tracker_name,128);
    18     get_tracker_port(node,&tracker_port);
    19 
    20     sprintf(request,
    21     "GET /announce?info_hash=%s&peer_id=%s&port=%u"
    22     "&uploaded=%lld&downloaded=%lld&left=%lld"
    23     "&event=started&key=%d&compact=1&numwant=%d HTTP/1.0
    "
    24     "Host: %s
    User-Agent: Bittorrent
    Accept: */*
    "
    25     "Accept-Encoding: gzip
    Connection: closed
    
    ",
    26     encoded_info_hash,encoded_peer_id,port,up,down,left,
    27     key,numwant,tracker_name);
    28 
    29 #ifdef DEBUG
    30     printf("request:%s
    ",request);
    31 #endif
    32 
    33     return 0;
    34 }
    View Code

    get_response_type() 分析返回的内容 确认返回内容的类型

     1 int get_response_type(char *buffer,int len,int *total_length)
     2 {
     3     int i, content_length = 0;
     4 
     5     for(i = 0; i < len-7; i++) {
     6         if(memcmp(&buffer[i],"5:peers",7) == 0) { 
     7             i = i+7;
     8             break; 
     9         }
    10     }
    11     if(i == len-7)        return -1;  // 返回的消息不含"5:peers"关键字
    12     if(buffer[i] != 'l')  return 0;   // 返回的消息的类型为第一种
    13 
    14     *total_length = 0;
    15     for(i = 0; i < len-16; i++) {
    16         if(memcmp(&buffer[i],"Content-Length: ",16) == 0) {
    17             i = i+16;
    18             break; 
    19         }
    20     }
    21     if(i != len-16) {
    22         while(isdigit(buffer[i])) {
    23             content_length = content_length * 10 + (buffer[i] - '0');
    24             i++;
    25         }
    26         for(i = 0; i < len-4; i++) {
    27             if(memcmp(&buffer[i],"
    
    ",4) == 0)  { i = i+4; break; }
    28         }
    29         if(i != len-4)  *total_length = content_length + i;
    30     }
    31 
    32     if(*total_length == 0)  return -1;
    33     else return 1;
    34 }
    View Code

    代码都比较清晰易懂 划分明确

    以上所有都是为了peer之间的通讯做准备 peer间的通讯流程如下

                      

    参考

    《linux C编程实战》

    作 者: itdef
    欢迎转帖 请保持文本完整并注明出处
    技术博客 http://www.cnblogs.com/itdef/
    B站算法视频题解
    https://space.bilibili.com/18508846
    qq 151435887
    gitee https://gitee.com/def/
    欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
    如果觉得不错,欢迎点赞,你的鼓励就是我的动力
    阿里打赏 微信打赏
  • 相关阅读:
    Andoid studio 使用Zxing扫描二维码
    WebServices新建及连接数据库
    Android 字典
    ADB Android Device Monitor 导出文件错误
    Android Studio 新建项目默认布局修改
    第九周时间进度表
    第七周学习进度表
    第六周学习进度表
    最优买书问题
    找水王2
  • 原文地址:https://www.cnblogs.com/itdef/p/9928997.html
Copyright © 2020-2023  润新知