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的过滤 ...
随机推荐
- Logparser介绍
原文链接:https://www.cnblogs.com/Jerseyblog/p/3986591.html Logparser是一款非常强大的日志分析软件,可以帮助你详细的分析网站日志.是所有数据分 ...
- P1348 Couple number
题目描述 任何一个整数N都能表示成另外两个整数a和b的平方差吗?如果能,那么这个数N就叫做Couple number.你的工作就是判断一个数N是不是Couple number. 输入输出格式 输入格式 ...
- angualrjs添加ngTouch
angularjs没有touch时间需要添加directive 插件代码如下 "use strict"; angular.module("ngTouch", [ ...
- python入门(十三):面向对象(继承、重写、公有、私有)
1. 三种类定义的写法 class P1:#定义类 加不加()都可以 pass class P2(): #带(),且括号中为空,类定义 pass ...
- linux 安装 kafka&zookeeper
安装kafka 1,下载kafka. #cd /usr/local #wget wget https://mirrors.tuna.tsinghua.edu.cn/apache/kafka/2.1.1 ...
- 安装setuptools 报错缺少zlib
# yum install zlib # yum install zlib-devel 下载成功后,进入python2.7的目录,重新执行 #make #make install 此时先前执行的 软连 ...
- 对于在git上面拉代码报"error: RPC failed; curl 56 OpenSSL SSL_read: SSL_ERROR_SYSCALL, errno 10054"解决方法
主要原因是安全设置的问题: 首先执行git config http.sslVerify "false" 若出现下列错误 git config http.sslVerify &q ...
- Python学习—基础篇之常用模块
常用模块 模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需要 ...
- FPGA驱动步进电机
步进电机 步进电机是将电脉冲信号转变为角位移或线位移的开环控制电机,是现代数字程序控制系统中的主要执行元件,应用极为广泛.在非超载的情况下,电机的转速.停止的位置只取决于脉冲信号的频率和脉冲数,而不受 ...
- innodb 关键特性(两次写与自适应哈希索引)
两次写: 场景: 当发生数据库宕机时,可能innodb存储引擎正在写入某个页到表中,而这个页只写了一部分,这种情况被称为部分写失效,如果发生,可以通过重做日志进行恢复,重做日志中记录的是对页的物理操作 ...