没有合适的资源?快使用搜索试试~ 我知道了~
BT软件下载开发完整版-01.doc
需积分: 9 24 下载量 106 浏览量
2008-10-06
14:24:47
上传
评论
收藏 1.53MB DOC 举报
温馨提示
试读
62页
BT软件下载开发完整版-00.doc 这是文本,如果你需要源码请发邮件给我: jinyu.zhu@gmail.com
资源推荐
资源详情
资源评论
448
项目实践:BT 下载软件的开发
第章
13
13.4.8 缓冲管理模块的设计和实现
缓冲管理模块维护一个大小为16MB的缓冲区(大小可调整),将下载到的数据先保存在缓冲
区中,在达到一定的数值时再将数据写入硬盘的文件中。peer请求数据时,先在缓冲区中寻找,若
缓冲区中不存在所请求的数据,则读文件并把请求数据所在的piece预先读入到缓冲区中。除了管
理缓冲区,本模块还负责创建待下载的文件,把下载到的piece写入文件,在peer请求数据时读文件
本模块由data.h和data.c构成。
data.h
#ifndef DATA_H
#define DATA_H
#include "peer.h"
// 每个Btcache结点维护一个长度为16KB的缓冲区,该缓冲区保存一个slice的数据
typedef struct _Btcache {
unsigned char *buff; // 指向缓冲区的指针
int index; // 数据所在的piece块的索引
int begin; // 数据在piece块中的起始位置
int length; // 数据的长度
unsigned char in_use; // 该缓冲区是否在使用中
unsigned char read_write; // 是发送给peer的数据还是接收到的数据
// 若数据是从硬盘读出,read_write值为0
// 若数据将要写入硬盘,read_write值为1
unsigned char is_full; // 缓冲区是否满
unsigned char is_writed; // 缓冲区中的数据是否已经写入到硬盘中
int access_count; // 对该缓冲区的访问计数
struct _Btcache *next;
} Btcache;
Btcache* initialize_btcache_node(); // 为Btcache结点分配内存空间并进行初始化
int create_btcache(); // 创建总大小为16K*1024即16MB的缓冲区
void release_memory_in_btcache(); // 释放data.c中动态分配的内存
int get_files_count(); // 获取种子文件中待下载的文件个数
int create_files(); // 根据种子文件中的信息创建保存下载数据的文件
// 判断一个Btcache结点中的数据要写到哪个文件以及具体位置,并写入
int write_btcache_node_to_harddisk(Btcache *node);
// 从硬盘读出一个slice的数据存放到缓冲区中,在peer需要时发送给peer
449
Linux 系统下的 C 编程
// 要读入的slice的索引,index、begin、length已存到node所指向的结点中
int read_slice_from_harddisk(Btcache *node);
// 检查一个piece的数据是否正确,若正确则写入硬盘上的文件
int write_piece_to_harddisk(int sequence,Peer *peer);
// 从硬盘上的文件中读取一个piece存放到p指针所指向的缓冲区中
int read_piece_from_harddisk(Btcache *p, int index);
// 将整个缓冲区中已下载的数据写入到硬盘上的文件中
int write_btcache_to_harddisk(Peer *peer);
// 当缓冲区不够用时,释放那些从硬盘上读取的piece
int release_read_btcache_node(int base_count);
// 从btcache缓冲区中清除那些未完成下载的piece
void clear_btcache_before_peer_close(Peer *peer);
// 将刚刚从peer处获取的一个slice存放到缓冲区中
i n t w r i t e _ s l i c e _ t o _ b t c a c h e ( i n t i n d e x , i n t b e g i n , i n t l e n g t h , u n s i g n e d c h a r * b u f f , i n t
len,Peer *peer);
// 从缓冲区获取一个slice,读取的slice存放到peer的发送缓冲区中
int read_slice_for_send(int index,int begin,int length,Peer *peer);
// 以下是为下载和上传最后一个piece而增加的函数
// 最后一个piece较为特殊,因为它是一个不完整的piece
int write_last_piece_to_btcache(Peer *peer);
int write_slice_to_last_piece(int index,int begin,int length,unsigned char *buff,int
len,Peer *peer);
int read_last_piece_from_harddisk(Btcache *p, int index);
int read_slice_for_send_last_piece(int index,int begin,int length,Peer *peer);
void release_last_piece();
#endif
每个缓冲区结点的大小为 16KB,默认生成1024个结点,总大小为 16MB。缓冲区以一个
piece(通常为256KB)为基本单位,也就是临近的16个结点为一组,这16个临近的结点要么全部被
使用要么全部空闲。第1~16个结点存放一个piece,第17~32个结点存放一个piece,依此类推。为
了方便处理,所有缓冲区在程序启动时统一申请,在程序结束时一起被释放。
以下是data.c文件的头部包含的代码,主要包含一些头文件和定义了一些全局变量。
data.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
450
项目实践:BT 下载软件的开发
第章
13
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <malloc.h>
#include "parse_metafile.h"
#include "bitfield.h"
#include "message.h"
#include "sha1.h"
#include "data.h"
extern char *file_name; // 待下载文件的文件名
extern Files *files_head; // 对于多文件种子有效,存放各个文件的路径和长度
extern int file_length; // 待下载文件的总长度
extern int piece_length; // 每个piece的长度
extern char *pieces; // 存放所有piece 的hash值
extern int pieces_length; // 缓冲区pieces的长度
extern Bitmap *bitmap; // 指向己方的位图
extern int download_piece_num; // 记录已经下载了多少个piece
extern Peer *peer_head; // 指向peer链表
#define btcache_len 1024 // 缓冲区中共有多少个Btcache结点
Btcache *btcache_head = NULL; // 指向一个大小为16MB的缓冲区
Btcache *last_piece = NULL; // 存放待下载文件的最后一个piece
int last_piece_index = 0; // 最后一个piece的索引,它的值为总piece数减1
int last_piece_count = 0; // 针对最后一个piece,记录已下载了多少个slice
int last_slice_len = 0; // 最后一个piece的最后一个slice的长度
int *fds = NULL; // 存放文件描述符
int fds_len = 0; // 指针fds所指向的数组的长度
int have_piece_index[64]; // 存放刚刚下载到的piece的索引
int end_mode = 0; // 是否进入了终端模式,终端模式的含义参考BT协议
data.c中各个函数的定义如下。
Btcache* initialize_btcache_node()
功能:创建Btcache结点,分配内存空间并对其成员的值进行初始化。函数实现代码如下:
Btcache* initialize_btcache_node()
{
Btcache *node;
451
Linux 系统下的 C 编程
node = (Btcache *)malloc(sizeof(Btcache));
if(node == NULL) { return NULL; }
node->buff = (unsigned char *)malloc(16*1024);
if(node->buff == NULL) { if(node != NULL) free(node); return NULL; }
node->index = -1;
node->begin = -1;
node->length = -1;
node->in_use = 0;
node->read_write = -1;
node->is_full = 0;
node->is_writed = 0;
node->access_count= 0;
node->next = NULL;
return node;
}
int create-btcadeu
功能:创建总大小为16K*1024bit即16MB的缓冲区。函数实现代码如下:
int create_btcache()
{
int i;
Btcache *node, *last; // node指向刚刚创建的结点、last指向缓冲区中最后一个结点
for(i = 0; i < btcache_len; i++) {
node = initialize_btcache_node();
if( node == NULL ) {
printf("%s:%d create_btcache error\n",__FILE__,__LINE__);
release_memory_in_btcache();
return -1;
}
if( btcache_head == NULL ) { btcache_head = node; last = node; }
else { last->next = node; last = node; }
}
// 为存储最后一个piece申请空间
int count = file_length % piece_length / (16*1024);
if(file_length % piece_length % (16*1024) != 0) count++;
last_piece_count = count; // count为最后一个piece所含的slice数
452
项目实践:BT 下载软件的开发
第章
13
last_slice_len = file_length % piece_length % (16*1024);
if(last_slice_len == 0) last_slice_len = 16*1024;
last_piece_index = pieces_length / 20 -1; // 最后一个piece的index值
while(count > 0) {
node = initialize_btcache_node();
if(node == NULL) {
printf("%s:%d create_btcache error\n",__FILE__,__LINE__);
release_memory_in_btcache();
return -1;
}
if(last_piece == NULL) { last_piece = node; last = node; }
else { last->next = node; last = node; }
count--;
}
for(i = 0; i < 64; i++) {
have_piece_index[i] = -1;
}
return 0;
}
void release_memory_in_btcache()
功能:释放data.c文件中动态分配的内存。函数实现代码如下:
void release_memory_in_btcache()
{
Btcache *p = btcache_head;
while(p != NULL) {
btcache_head = p->next;
if(p->buff != NULL) free(p->buff);
free(p);
p = btcache_head;
}
release_last_piece();
if(fds != NULL) free(fds);
}
void release_last_piece()
功能:释放为存储最后一个piece而申请的空间。函数实现代码如下:
void release_last_piece()
剩余61页未读,继续阅读
资源评论
zhujy_2002
- 粉丝: 0
- 资源: 6
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功