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 }
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 }
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 }
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 }
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 }
代码都比较清晰易懂 划分明确
以上所有都是为了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驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力
欢迎转帖 请保持文本完整并注明出处
技术博客 http://www.cnblogs.com/itdef/
B站算法视频题解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力