Linux BT下载(15)-连接Tracker模块的设计和实现

本文介绍Linux下连接Tracker模块的功能,包括构造HTTP请求,建立Tracker连接及解析Tracker响应数据。Tracker响应数据采用B编码,返回内容包含种子数、连接间隔和peer信息。内容涉及tracker.h和tracker.c的实现,以及http_encode和get_tracker_name等函数。
摘要由CSDN通过智能技术生成

连接Tracker模块的设计和实现

连接Tracker模块的主要功能是:构造HTTP请求,请求Tracker服务器发送peer的IP地址和端口号;与Tracker建立连接;解析从Tracker返回的数据。Tracker返回的数据是经过B编码的,解析Tracker的回应和解析种子文件是类似的。

本模块由tracker.h和tracker.c构成。

以下是tracker.h的代码:

#ifndef  TRACKER_H
#define  TRACKER_H
#include <netinet/in.h>
#include "parse_metafile.h"

typedef struct _Peer_addr {
	char ip[16];
	unsigned short port;
	struct _Peer_addr *next;
} Peer_addr;

//  用于将info_hash和peer_id转换为http编码格式
//  http协议规定,传输数据中的非数字和非字母都要进行编码转换
int http_encode(unsigned char *in,int len1,char *out,int len2);
//  从种子文件中存储的tracker的URL获取tracker主机名
int get_tracker_name(Announce_list *node,char *name,int len);
//  从种子文件中存储的tracker的URL获取tracker端口号
int get_tracker_port(Announce_list *node,unsigned short *port);

//  创建发送到tracker服务器的请求信息
int create_request(char *request, int len,Announce_list *node,
				   unsigned short port,long long down,long long up,
				   long long left,int numwant);

//  准备连接tracker
int prepare_connect_tracker(int *max_sockfd);
//  准备连接peer
int prepare_connect_peer(int *max_sockfd);

//  获取tracker返回的消息的类型
//  一种类型为"5:peers"关键字之后是一个字符串,另一种是一个列表
int get_response_type(char *buffer,int len,int *total_length);
//  解析第一种tracker返回的消息
int parse_tracker_response1(char *buffer,int ret,char *redirection,int len);
//  解析第二种tracker返回的消息
int parse_tracker_response2(char *buffer,int ret);
//  将与之建立连接的peer加入到peer列表中
int add_peer_node_to_peerlist(int *sock,struct sockaddr_in saptr);

void free_peer_addr_head();
//  释放本文件函数中动态分配的内存以防止内存泄漏
void release_memory_in_tracker();

#endif

tracker.c的文件的头部包含的代码如下:

#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <errno.h>
#include <ctype.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include "parse_metafile.h"
#include "peer.h"
#include "tracker.h"

extern unsigned char info_hash[20];
extern unsigned char peer_id[20];
extern Announce_list *announce_list_head;

extern int *sock;
extern struct sockaddr_in *tracker;
extern int *valid;
extern int tracker_count;

extern int *peer_sock;
extern struct sockaddr_in *peer_addr;
extern int *peer_valid;
extern int peer_count;

Peer_addr *peer_addr_head = NULL;

tracker.c的函数的定义如下:

int http_encode(unsigned char *in, int len1, char *out, int len2)

/*
*功能:根据HTTP协议进行编码转换
*传入参数:
*	*in 
*	len1
*传出参数:
*	*out
*	len2
*返回值:
* -1	错误
* 0
*/
int http_encode(unsigned char *in,int len1,char *out,int len2)
{
	int  i, j;
	char hex_table[16] = "0123456789abcdef"; 
	
	if( (len1 != 20) || (len2 <= 90) )  
	{
		return -1;
	}	
	
	for(i = 0, j = 0; i < 20; i++, j++) 
	{
		if( isalpha(in[i]) || isdigit(in[i]) )
		{//英文字符
			out[j] = in[i];
		}
		else 
		{ 
			out[j] = '%';
			j++;
			out[j] = hex_table[in[i] >> 4];//取出ASCII码的高四位
			j++;
			out[j] = hex_table[in[i] & 0xf];//取出ASCII码的低四位
		}
	}
	out[j] = '\0';
	
#ifdef DEBUG
	//printf("http encoded:%s\n",out);
#endif
	
	return 0;
}
代码说明:进行编码转换,根据HTTP协议,HTTP请求中的非数字和非字母都有进行编码转换。例如:空格符既不属于0~9也不属于a~z、A~Z,需要进行转换,它的ASCII码为0x20,转换为字符串“%20”

int get_tracker_name(Announce_list *node, char *name, int len)

/*
*功能:获取Tracker URL中的主机名
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值