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] = '\0';
19     
20 #ifdef DEBUG
21     //printf("http encoded:%s\n",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] = '\0';
15 
16 #ifdef DEBUG
17     printf("%s\n",node->announce);
18     printf("tracker name:%s\n",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\n",*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\r\n"
24     "Host: %s\r\nUser-Agent: Bittorrent\r\nAccept: */*\r\n"
25     "Accept-Encoding: gzip\r\nConnection: closed\r\n\r\n",
26     encoded_info_hash,encoded_peer_id,port,up,down,left,
27     key,numwant,tracker_name);
28 
29 #ifdef DEBUG
30     printf("request:%s\n",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],"\r\n\r\n",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编程实战》

posted on 2018-11-08 14:44  itdef  阅读(375)  评论(0编辑  收藏  举报

导航