bittorrent 学习(四) tracker peer通讯
看看 tracker.c文件
http_encode() 为http发送进行编码转换
int http_encode(unsigned char *in,int len1,char *out,int len2)
{
int i, j;
char hex_table[] = "0123456789abcdef"; if( (len1 != ) || (len2 <= ) ) return -;
for(i = , j = ; i < ; i++, j++) {
if( isalpha(in[i]) || isdigit(in[i]) )
out[j] = in[i];
else {
out[j] = '%';
j++;
out[j] = hex_table[in[i] >> ];
j++;
out[j] = hex_table[in[i] & 0xf];
}
}
out[j] = '\0'; #ifdef DEBUG
//printf("http encoded:%s\n",out);
#endif return ;
}
get_tracker_name() 通过截取关键字符 获取网址的名称部分
int get_tracker_name(Announce_list *node,char *name,int len)
{
int i = , j = ; if( (len < ) || (node == NULL) ) return -;
if( memcmp(node->announce,"http://",) == )
i = i + ;
while( (node->announce[i] != '/') && (node->announce[i] != ':') ) {
name[j] = node->announce[i];
i++;
j++;
if( i == strlen(node->announce) ) break;
}
name[j] = '\0'; #ifdef DEBUG
printf("%s\n",node->announce);
printf("tracker name:%s\n",name);
#endif return ;
}
get_tracker_port() 通过截取关键字符 获取端口部分
int get_tracker_port(Announce_list *node,unsigned short *port)
{
int i = ; if( (node == NULL) || (port == NULL) ) return -;
if( memcmp(node->announce,"http://",) == ) i = i + ;
*port = ;
while( i < strlen(node->announce) ) {
if( node->announce[i] != ':') { i++; continue; } i++; // skip ':'
while( isdigit(node->announce[i]) ) {
*port = *port * + (node->announce[i] - '');
i++;
}
break;
}
if(*port == ) *port = ; #ifdef DEBUG
printf("tracker port:%d\n",*port);
#endif return ;
}
create_request()创建一个http的请求
int create_request(char *request,int len,Announce_list *node,
unsigned short port,long long down,long long up,
long long left,int numwant)
{
char encoded_info_hash[];
char encoded_peer_id[];
int key;
char tracker_name[];
unsigned short tracker_port; http_encode(info_hash,,encoded_info_hash,);
http_encode(peer_id,,encoded_peer_id,); srand(time(NULL));
key = rand() / ; get_tracker_name(node,tracker_name,);
get_tracker_port(node,&tracker_port); sprintf(request,
"GET /announce?info_hash=%s&peer_id=%s&port=%u"
"&uploaded=%lld&downloaded=%lld&left=%lld"
"&event=started&key=%d&compact=1&numwant=%d HTTP/1.0\r\n"
"Host: %s\r\nUser-Agent: Bittorrent\r\nAccept: */*\r\n"
"Accept-Encoding: gzip\r\nConnection: closed\r\n\r\n",
encoded_info_hash,encoded_peer_id,port,up,down,left,
key,numwant,tracker_name); #ifdef DEBUG
printf("request:%s\n",request);
#endif return ;
}
get_response_type() 分析返回的内容 确认返回内容的类型
int get_response_type(char *buffer,int len,int *total_length)
{
int i, content_length = ; for(i = ; i < len-; i++) {
if(memcmp(&buffer[i],"5:peers",) == ) {
i = i+;
break;
}
}
if(i == len-) return -; // 返回的消息不含"5:peers"关键字
if(buffer[i] != 'l') return ; // 返回的消息的类型为第一种 *total_length = ;
for(i = ; i < len-; i++) {
if(memcmp(&buffer[i],"Content-Length: ",) == ) {
i = i+;
break;
}
}
if(i != len-) {
while(isdigit(buffer[i])) {
content_length = content_length * + (buffer[i] - '');
i++;
}
for(i = ; i < len-; i++) {
if(memcmp(&buffer[i],"\r\n\r\n",) == ) { i = i+; break; }
}
if(i != len-) *total_length = content_length + i;
} if(*total_length == ) return -;
else return ;
}
代码都比较清晰易懂 划分明确
以上所有都是为了peer之间的通讯做准备 peer间的通讯流程如下


参考
《linux C编程实战》
bittorrent 学习(四) tracker peer通讯的更多相关文章
- TweenMax动画库学习(四)
目录 TweenMax动画库学习(一) TweenMax动画库学习(二) TweenMax动画库学习(三) Tw ...
- SVG 学习<四> 基础API
目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...
- Android JNI学习(四)——JNI的常用方法的中文API
本系列文章如下: Android JNI(一)——NDK与JNI基础 Android JNI学习(二)——实战JNI之“hello world” Android JNI学习(三)——Java与Nati ...
- SCARA——OpenGL入门学习四(颜色)
OpenGL入门学习[四] 本次学习的是颜色的选择.终于要走出黑白的世界了~~ OpenGL支持两种颜色模式:一种是RGBA,一种是颜色索引模式. 无论哪种颜色模式,计算机都必须为每一个像素保存一些数 ...
- ZigBee学习四 无线+UART通信
ZigBee学习四 无线+UART通信 1) 协调器编程 修改coordinator.c文件 byte GenericApp_TransID; // This is the unique messag ...
- (转)SpringMVC学习(四)——Spring、MyBatis和SpringMVC的整合
http://blog.csdn.net/yerenyuan_pku/article/details/72231763 之前我整合了Spring和MyBatis这两个框架,不会的可以看我的文章MyBa ...
- Spring Boot 项目学习 (四) Spring Boot整合Swagger2自动生成API文档
0 引言 在做服务端开发的时候,难免会涉及到API 接口文档的编写,可以经历过手写API 文档的过程,就会发现,一个自动生成API文档可以提高多少的效率. 以下列举几个手写API 文档的痛点: 文档需 ...
- Expression Blend学习四控件
原文:Expression Blend学习四控件 Expression Blend制作自定义按钮 1.从Blend工具箱中添加一个Button,按住shift,将尺寸调整为125*125; 2.右键点 ...
- day 83 Vue学习四之过滤器、钩子函数、路由、全家桶等
Vue学习四之过滤器.钩子函数.路由.全家桶等 本节目录 一 vue过滤器 二 生命周期的钩子函数 三 vue的全家桶 四 xxx 五 xxx 六 xxx 七 xxx 八 xxx 一 Vue的过滤 ...
随机推荐
- HU-1043
http://acm.hdu.edu.cn/showproblem.php?pid=1043 由于HDU这里的涉及多组数据,而每组数据按照一般的bfs()做法,即遍历每一种可行方案都保存一次路径,直到 ...
- 关于java使用POI导出ppt ,其中表格setText 失败问题
1.导出ppt 必要的包 使用maven <dependency> <groupId>org.apache.poi</groupId> <artifactId ...
- spring配置文件注入到静态变量
spring配置注入到静态文件代码如下: package com.test.oss; import org.springframework.beans.factory.annotation.Value ...
- springboot性能优化
一.扫描优化 原文链接:http://www.studyshare.cn/blog-front/blog/details/1135 SpringBoot项目中的启动类,会使用@SpringBootAp ...
- ThreadLocal总结
一.问题抛出 SimpleDateFormat是非线程安全的,在多线程情况下会遇见问题: public static void main(String[] args) { ExecutorServic ...
- html:布局class名和其他class名个人整理总结
一:app 二:header 三:main 四:footer 1:中横杠:布局(main-top.main-left等) 2:下横杠:状态(item-active:选中等)
- LevelDB源码分析-Open
Open LevelDB的初始化主要由Open函数实现: Status DB::Open(const Options &options, const std::string &dbna ...
- python os.path.isfile函数
最近刚开始学习Python,做了个小练习:扫描当前目录及其子目录中的文件,找出文件名中含有指定关键字的文件并打印文件名.思路很简单,如果是文件则判断是否满足条件:如果是目录则进入目录搜索文件,递归. ...
- RabbitMQ的安装与配置
一.安装环境 CentOS6.3 64位操作系统. 二.安装文件 1.安装erlang:Rabbitmq是基于erlang语言开发的,所以先需要安装erlang:我选择的安装包是:erlang-17. ...
- 判断序列B是否是序列A的连续子序列
算法思想:因为两个整数序列已存入两个链表中,操作从两个链表的第一个结点开始,若对应得数据相等,则后移指针,若对应的数据不等,则A列表从上次开始比较结点的后继开始,B链表仍从第一个结点开始,直到B链表到 ...