看看 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通讯的更多相关文章

  1. TweenMax动画库学习(四)

    目录            TweenMax动画库学习(一)            TweenMax动画库学习(二)            TweenMax动画库学习(三)            Tw ...

  2. SVG 学习<四> 基础API

    目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...

  3. Android JNI学习(四)——JNI的常用方法的中文API

    本系列文章如下: Android JNI(一)——NDK与JNI基础 Android JNI学习(二)——实战JNI之“hello world” Android JNI学习(三)——Java与Nati ...

  4. SCARA——OpenGL入门学习四(颜色)

    OpenGL入门学习[四] 本次学习的是颜色的选择.终于要走出黑白的世界了~~ OpenGL支持两种颜色模式:一种是RGBA,一种是颜色索引模式. 无论哪种颜色模式,计算机都必须为每一个像素保存一些数 ...

  5. ZigBee学习四 无线+UART通信

    ZigBee学习四 无线+UART通信 1) 协调器编程 修改coordinator.c文件 byte GenericApp_TransID; // This is the unique messag ...

  6. (转)SpringMVC学习(四)——Spring、MyBatis和SpringMVC的整合

    http://blog.csdn.net/yerenyuan_pku/article/details/72231763 之前我整合了Spring和MyBatis这两个框架,不会的可以看我的文章MyBa ...

  7. Spring Boot 项目学习 (四) Spring Boot整合Swagger2自动生成API文档

    0 引言 在做服务端开发的时候,难免会涉及到API 接口文档的编写,可以经历过手写API 文档的过程,就会发现,一个自动生成API文档可以提高多少的效率. 以下列举几个手写API 文档的痛点: 文档需 ...

  8. Expression Blend学习四控件

    原文:Expression Blend学习四控件 Expression Blend制作自定义按钮 1.从Blend工具箱中添加一个Button,按住shift,将尺寸调整为125*125; 2.右键点 ...

  9. day 83 Vue学习四之过滤器、钩子函数、路由、全家桶等

    Vue学习四之过滤器.钩子函数.路由.全家桶等   本节目录 一 vue过滤器 二 生命周期的钩子函数 三 vue的全家桶 四 xxx 五 xxx 六 xxx 七 xxx 八 xxx 一 Vue的过滤 ...

随机推荐

  1. (20/24) webpack实战技巧:watch实现热打包和添加代码备注

    在前面的学习中,我们一直使用webpack-dev-server充当(本地)服务器和完成打包任务,但是当出项目团队联合开发,共同使用一个服务器时,这时候我们需要实时进行打包以确保团队间能进行联调或者进 ...

  2. Kubernetes dashboard安装

    1. To download Dashboard plugin deployment YAML file from internet. #cd /home #mkdir k8s #cd k8s # w ...

  3. Javascript 京东轮播图

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...

  4. 3.Telnet探测端口后怎么退出

    使用 'Ctrl' +  ' ] ' 一起按退出

  5. EFM32之GPIO

    配置时钟: void CMU_ClockEnable(CMU_Clock_TypeDef clock, bool enable) CMU_ClockEnable(cmuClock_HFPER, tru ...

  6. 如何设置.net控件SplitContainer平均分配

    设置SplitterDistance为宽或者高的一半

  7. 关于ASP.NET 服务器报错 Server Error in '/' Application Runtime Error 错误及解决方法

    今天遇到一个错误 程序在服务器上运行时报错 先贴上错误代码 自己也在网上找了一些解决方法,把错误定位到服务器的配置文件也就是Web.config的问题, 于是在system.web节点下 加上cust ...

  8. 随想:目标识别中,自适应样本均衡设计,自适应模型结构(参数可变自适应,模型结构自适应,数据类别or分布自适应)

    在现在的机器学习中,很多人都在研究自适应的参数,不需要人工调参,但是仅仅是自动调参就不能根本上解决 ai识别准确度达不到实际生产的要求和落地困难的问题吗?结论可想而知.如果不改变参数,那就得从算法的结 ...

  9. Loadrunner进行HTTPS协议性能测试

    1.最简单办法就是在脚本前面加上:web_set_sockets_option("SSL_VERSION","TLS"),一般能解决HTTPS协议的请求问题,无 ...

  10. win10卸载IE11后从新安装

    win10卸载IE11后想要从新安装,运气不好的话各种坑安装不上,运气好就不说了.这里笔者在知乎看到一种方法,亲测可用,记录如下: 设置--应用--应用和功能--管理可选功能--添加功能--Inter ...