看看 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. Exception in thread "main" java.lang.UnsupportedClassVersionError

    Exception in thread “main" java.lang.UnsupportedClassVersionError这个报错是用高版本JDK编译项目或文件产生的class文件, ...

  2. DBUtils工具类

    import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql. ...

  3. Jmeter安装使用

    Jmeter的安装与使用 首先,安装Jmeter需要JDK https://www.oracle.com/technetwork/java/javase/downloads/index.html 配置 ...

  4. python_14 多态,封装

    多态: 由不同的类实例化得到的对象,调用同一个方法,执行的逻辑不同. 多态的概念指出了对象如何通过他们的共同的属性和动作来操作及访问,而不需考虑他们的类. class H2O: def __init_ ...

  5. 分享一个微信自动跳转外部浏览器下载app的api接口!

    现在微信渠道可以说是拉新最快的渠道,因为微信具备强裂变性.但是目前微信对第三方下载链接的拦截是越来越严格了,那么想要在微信内肆无忌惮地推广链接就需要用到微信跳转浏览器的接口,那如何获取该接口呢?   ...

  6. UVa442 Matrix Chain Multiplication(栈)

    #include<cstdio>#include<cstring> #include<stack> #include<algorithm> #inclu ...

  7. socket.io诡异的问题

    在socket.io客户端连接的时候,如果传入的query包含“sid”这个键时会报错,不知道具体原因.

  8. SQL游标在递归是的时候提示 "游标" 名称已经存在的问题

    游标的语法: DECLARE cursor_name CURSOR [ LOCAL | GLOBAL ] [ FORWARD_ONLY | SCROLL ] [ STATIC | KEYSET | D ...

  9. crontab,定时任务执行找不到库or shell可执行,crontab 定时任务下就不能执行,tensorflow,ImportError: libcuda.so.1: cannot open shared object file: No such file or directory

    在线上启动一个定时任务,但是起来查看,发现任务执行找不到库,报cuda错误: ImportError: libcuda.so.1: cannot open shared object file: No ...

  10. Eclipse设置类,方法注释模版

    首先打开Eclipse配置选项:Window->Preference->Java->Code Style->Code Template 配置Comments下的每个选项的模版, ...