bt软件下载开发完整版-01(编辑修改稿)内容摘要:
p = pnext。 } } return 0。 } 454 Linux 系统 下的 C 编程 int read_slice_from_harddisk(Btcache *node) 功能:从硬盘读一个 slice 的数据,存放到缓冲区中,在 peer 需要时发送给 peer。 该函数非常类似于 write_btcache_node_to_harddisk,限于篇幅此处不再列出。 具体代码请参考本书所附源代码。 int write_piece_to_harddisk(int sequence,Peer *peer) 功能:检查下载完的一个 piece 的数据是否正确,若正确则写入文件。 参数: sequence 是存放 piece 的第一个 slice 的 Btcache 结点编号,该值的范围为 0~ 1023 中16 的整数值函数实现代码如下所示: int write_piece_to_harddisk(int sequence,Peer *peer) { Btcache *node_ptr = btcache_head, *p。 unsigned char piece_hash1[20], piece_hash2[20]。 int slice_count = piece_length / (16*1024)。 // 一个 piece所含的 slice数 int index, index_copy。 if(peer==NULL) return 1。 int i = 0。 while(i sequence) { node_ptr = node_ptrnext。 i++。 } p = node_ptr。 // p指针指向 piece的第一个 slice所在的 btcache结点 // 计算刚刚下载到的这个 piece的 hash 值 SHA1_CTX ctx。 SHA1Init(amp。 ctx)。 while(slice_count0 amp。 amp。 node_ptr!=NULL) { SHA1Update(amp。 ctx,node_ptrbuff,16*1024)。 slice_count。 node_ptr = node_ptrnext。 } SHA1Final(piece_hash1,amp。 ctx)。 // 从种子文件中获取该 piece的正确的 hash值 index = pindex * 20。 index_copy = pindex。 // 存放 piece的 index for(i = 0。 i 20。 i++) piece_hash2[i] = pieces[index+i]。 // 比较两个 hash值,若两者一致说明下载了一个正确的 piece int ret = memcmp(piece_hash1,piece_hash2,20)。 if(ret != 0) { printf(piece hash is wrong\n)。 return 1。 } // 将该 piece的所有 slice写入文件 node_ptr = p。 slice_count = piece_length / (16*1024)。 while(slice_count 0) { write_btcache_node_to_harddisk(node_ptr)。 // 在 peer的请求队列中删除 piece请 求 Request_piece *req_p = peerRequest_piece_head。 Request_piece *req_q = peerRequest_piece_head。 while(req_p != NULL) { if(req_pbegin==node_ptrbegin amp。 amp。 req_pindex==node_ptrindex) { if(req_p == peerRequest_piece_head) 455 项目实践: BT 下载软件的开发 第章 13 peerRequest_piece_head = req_pnext。 else req_qnext = req_pnext。 free(req_p)。 req_p = req_q = NULL。 break。 } req_q = req_p。 req_p = req_pnext。 } node_ptrindex = 1。 node_ptrbegin = 1。 node_ptrlength = 1。 node_ptrin_use = 0。 node_ptrread_write = 1。 node_ptris_full = 0。 node_ptris_writed = 0。 node_ptraccess_count = 0。 node_ptr = node_ptrnext。 slice_count。 } // 当前处于终端模式,则在 peer链表中删除所有对该 piece 的请求 if(end_mode == 1) delete_request_end_mode(index_copy)。 // 更新位图 set_bit_value(bitmap,index_copy,1)。 // 保存 piece的 index,准备给所有的 peer 发送 have消息 for(i = 0。 i 64。 i++) { if(have_piece_index[i] == 1) { have_piece_index[i] = index_copy。 break。 } } // 更新 download_piece_num,每下载 10个 piece就将位图写入文件 download_piece_num++。 if(download_piece_num % 10 == 0) restore_bitmap()。 // 打印出提示信息 printf(%%%%%% Total piece download:%d %%%%%%\n,download_piece_num)。 printf(writed piece index:%d \n,index_copy)。 return 0。 } int read_piece_from_harddisk(Btcache *p, int index) 功能:从硬盘上的文件中读取一个 piece 到 p 指针所指向的缓冲区中。 函数实现的代码如下: int read_piece_from_harddisk(Btcache *p, int index) { Btcache *node_ptr = p。 int begin = 0。 int length = 16*1024。 int slice_count = piece_length / (16*1024)。 int ret。 if(p==NULL || index=pieces_length/20) return 1。 while(slice_count 0) { node_ptrindex = index。 node_ptrbegin = begin。 node_ptrlength = length。 456 Linux 系统 下的 C 编程 ret = read_slice_from_harddisk(node_ptr)。 if(ret 0) return 1。 node_ptrin_use = 1。 node_ptrread_write = 0。 node_ptris_full = 1。 node_ptris_writed = 0。 node_ptraccess_count = 0。 begin += 16*1024。 slice_count。 node_ptr = node_ptrnext。 } return 0。 } int write_btcache_to_harddisk(Peer *peer) 功能:将整个缓冲区中已下载的 piece 写入硬盘,这样可以释放缓冲区。 函数实现的代码如下: int write_btcache_to_harddisk(Peer *peer) { Btcache *p = btcache_head。 int slice_count = piece_length / (16*1024)。 int index_count = 0。 int full_count = 0。 int first_index。 while(p != NULL) { if(index_count % slice_count == 0) { full_count = 0。 first_index = index_count。 } if( (pin_use == 1) amp。 amp。 (pread_write == 1) amp。 amp。 (pis_full == 1) amp。 amp。 (pis_writed == 0) ) { full_count++。 } if(full_count == slice_count) { write_piece_to_harddisk(first_index,peer)。 } index_count++。 p = pnext。 } return 0。 } int release_read_btcache_node(int base_count) 功能:当缓冲区不够用时,释放那些从硬盘上读取的 piece。 函数实现代码如下: int release_read_btcache_node(int base_count) { Btcache *p = btcache_head。 Btcache *q = NULL。 int count = 0。 int used_count = 0。 int slice_count = piece_length / (16*1024)。 if(base_count 0) return 1。 while(p != NULL) { 457 项目实践: BT 下载软件的开发 第章 13 if(count % slice_count == 0) { used_count = 0。 q = p。 }。bt软件下载开发完整版-01(编辑修改稿)
相关推荐
虑的范围,这时候你就会发现在调用脚本时直接加入参数,可以使代码效率加倍。 By the way,上面的这几个脚本,都是 病毒的一部分,在后面的教程里,大家将有机会见到这个病毒的真面目。 那是不是说,在同一个目录下至少存在两个批处理脚本文件(只有一个你调用谁。 )。 呵呵,注意了,这句话错了。 只有一个照样可以调用 调用自身。 看例九(默认脚本文件名 ): send %1 This is a
w Test99 的 What is important when … ? Test99 的 Entering a new foreign Test99 的 * Export directly using the existing sale Test99 的 * Find a jointventure Test99Part 3: Collaborative Test99Negoti
: 我想我可以从这些数据 得出 结论 ,并 提出答复保罗的意见供你参考。 Patricia: Wen, do you think you can do these tasks for me in a week? 帕特丽夏: 文 ,你认为你一周能完成这些任务吗。 Wen: I am fairly confident that I could do these four tasks in a
免费的东西,而并非开玩笑。 将它们设计得富有乐趣,那它们则能让浏览者产生兴趣。 向消费者显示 出你的质量、建立起你的信用。 避免广告条有 “我们想赚你的钱 ”这样的意思。 试试以下的方法: 把美女放在 BANNER 的左边。 这是一个很好的方法,来介绍你的网站给个人用户某些东西或能让他们做什么。 通过给新用户一定的益处来欢迎他们是很重要的,然后再开始用做广告来向他 们销售产品。
( ) 求得圓心座標點 指定圓的半徑或 [直徑 (D)] : 10 輸入半徑 精選應用 13:已知矩形條件如下: 指令 : RECTANG 指定第一個角點或 [倒角 (C)/高程 (E)/圓角 (F)/厚度 (T)/線寬 (W)]: 選取左下角點 指定其它角點 : 39。 CAL 表示式 : [@sqr(),sqrt(2)*] 輸入表示式 ( ) 求得另一角座標點 精選應用 1:已知一個任意圓
方法是将 AutoCAD R14下 Support子目录下的 AutoCAD R13的 Support子目录下。 15. AutoCAD中 ,它记录命令缩写内容,用户可自定义它们,格式如下: 命令缩写 *命令名称。 也可定义系统命令, AutoCAD R14提供了 sh命令,可执行 DOS命令,但在 Windows下作用不大。 R14中用 NOTEPAD、 EDIT、 DIR、 DEL等系统命令