星期一, 七月 31, 2006

漫画下载工具更新



这两天又抓到个在线漫画的站点使我原来那个漫画下载工具又有了用武之地,修改了点源码就这么用了起来,不过还是发现htmlparser的穿透力不够强,又再一次分析不出<a>标签,使原来一个递归的结束标志不能使用,还好其使用的是asp还有点page数字的规律使暂时算解决了这个问题。还有点bug在下载测试中给找出,特别是在多次下载之后指针偏移的问题也得到了解决,现在可以正常的多次下载了。


附上更新日志:





v0.05更新:





修正bug:

1.修正原来下载>100幅图片时的覆盖错误

2.修正多次下载造成没有下载内容的bug,现在可以正常多次下载





界面改善:

1.输出滚动条自动滚动,可随时注意了解进度

2.下载完成后出现完成声,提示下载完成

3.输入框被选中即为全选,方便输入


4.输入完成按回车可以直接运行程序

星期六, 七月 29, 2006

新书入手



经过一个星期的等待,在joyo订购的图书终于于今天送到了家里。瞅着这厚厚的十来本书,睡前又有事可做了,不至于再漫无目的的胡思乱想了。


有着超越《Lord of Rings》三部曲的奇幻小说《A song of ice and fire》在长时间的缺货后终于来到了我的身旁,望着它们,剑与魔法,传奇和阴谋的世界在向我招手!傅佩荣的《哲学与人生》是经过多人的推荐的一本哲学相关的图书,是本从苏格拉底到孔子,从存在主义到道家的智慧,从神话悲剧到文化视野,从审美到宗教的智慧之书。然后是中华书局的《三国志》。中华书局作为一家资深的古籍出版社在近期推出了24史系列图书,全部是繁体竖版给人以一种古书的感觉。看到书第一感觉是书好像太薄了,之后拿起来随手翻了下是(宋)裴松之所注还不错。现在就慢慢的集钱争取把24史全买回家好好看。最后是著名的《代码大全(第二版)》,一本没得说的好书。


最后希望的是书不要像黄生借书说中高束焉那样,而是发挥其价值。

星期一, 七月 24, 2006

很多东西其实不简单



这两天使用c++builder,感觉c++builder的控件太简单易用了。但究其实质却不知其内部是如何工作。虽然有过读过《深入浅出MFC》的经验,但我们很多时候还是会给华丽的外表所迷惑,而不去深究其底层真正的工作原理,难道这才是我们要学习的吗?不禁让我想起在csdn上看到的一张帖子,话说MS的专家说作为一个程序员根本不需要去探究更深层的东西,而只要会使用MS的天才架构师和牛人们所提供架构就可以了。难道说我们所要做的就是廉价劳力吗?

星期日, 七月 23, 2006



今天一天感觉混混沌沌的,即使在编程时亦是如此。原因在于今天早上的梦一直萦绕在心头。虽然一觉醒来对于梦的记忆也是断断续续的,不过即使在如此支离破碎的记忆中也表现出离奇的一斑,很多片断都经不起逻辑的推断。但在其中又能看到一些平时不经意间读到或看到的东西的缩影。不过最让我感到离奇的且是记忆最深刻的是其中有一人竟是永不喝无色透明色的液体,究其因是这些东西和眼泪的颜色的相同,可见在其生命中充斥着太多的泪水了。真不知道这是如何会被我想象出来的?也许是我想的太多了,对于太多东西都喜欢刨根问底而让这混混沌沌的感觉充斥着今天一整天。



PS:也许是我到现在还没真正完全的清醒吧,混沌之下作此文,胡言乱语居多,大家就将就着看吧。

星期五, 七月 14, 2006

从im软件想起



这两天老妈嫌我晚上太吵,只好早早的关机上床。躺在床上又睡不着,这时不知怎么的考虑起im软件如何对动态ip进行p2p的连接。回想起tcp及udp都是以ip作为路由目的协议,没有固定的ip如何使别人连接到你呢?转而又想到无论是msn还是qq都有其服务器,难道是上线时先发消息给其服务器注册ip然后再在其服务器上下载其他联机者的ip到本地?在随后的时间里我很想打破此设想,但又想不出其他可行性。难道说对于动态ip一定要有服务器来提供ip路由表?就没有其他办法实现了吗?希望在今后能更加深入的了解。

星期一, 七月 03, 2006

又一个朋友要远行了,让我们为他祝福吧!



今天中午在睡梦中给急促的电话声吵醒,拿起电话听见电话那头肉肉的声音,他告诉我大鱼头去英国留学,今天一起出去吃顿饭,叫我到他家里跟他和老狗一起去。便洗洗弄弄出门到了肉肉家,又跟肉和狗一起到了预定的地点。



随着主角的到场,原来有很多话说但霎时像一下子被抽空似的没有了一句言语。从开席到散席默默地一直坐着,即使是送礼物的时候也没有多说几句。虽然期间不乏耳边听着多种多样的个人逸事,看着各式各样的历史重放但总是提不起精神进入其中。难道是看着朋友的远行自发的从心底涌现出悲伤的情绪仰或是感慨朋友一个又一个的出国了而再没有很多的机会碰面?现在再回头想想也没有什么,虽然两年的时间不短,但亦不长。两年後还是可以再见面的,还有现代化的工具,何必弄的像这样呢。最后让我们为他祝福:一帆风顺吧!

对于bt运作方式的猜想



今天在公交车上发呆,一时兴起想研究下bt是如何工作的。便做出了如下猜想:



由于bt是p2p的,我认为bt的服务器的作用是用来记录各个连接上服务器的计算机的ip和端口的路由表,然后由bt软件下载此路由表来实现p2p的下载和上传。然后再上传进度下载进度到此服务器来建立另一张下载进度表。也就是说由第一个种子给出他的ip和端口上传给服务器,再由各个下载者来下载此路由表,然后用此ip和端口直接连上此计算机来实现上传和下载,其他亦然。



btw:猜想而已,未得到考证。等会去网上看看是否正确哈。





附转自http://blog.csdn.net/wuyanhuiyishi/的官方的BitTorrent协议详解











BitTorrent(简称BT,比特洪流)是一个文件分发协议。它通过URL识别内容并且和网络无缝结合。它和普通HTTP协议相比优势在于,同时下载一个文件的下载者在下载同时不断互相上传数据,使文件源可以在很有限的负载增加的情况下支持大量下载者同时下载。




一个BT式文件分发需要以下实体:



·一个普通网络服务器

·一个静态元信息文件('Metainfo' file)

·一个BT Tracker

·一个“原始”下载者('original' downloader)

·网络终端的浏览器

·网络终端的下载者



这里假设理想情况下一个文件有多个网络终端的下载者。




架设一个BT服务器步骤如下:



1.开始运行Tracker(已运行的跳过这一步);

2.开始运行普通网络服务器程序,如Apache,已运行的跳过这一步;


3.在网络服务器上将.torrent文件关联到Mime类型
application/x-bittorrent(已做过关联的跳过这一步);


4.用要发布的完整文件和Tracker的URL创建一个元信息文件(.torrent文件);


5.将元信息文件放置在网络服务器上;

6.在网页上发布元信息文件(.torrent文件)的链接;


7.原始下载者开始提供完整的文件(原本)。



通过BT下载步骤如下:



1.安装BT客户端程序(已安装的跳过这一步);

2.上网;

3.点击一个链到.torrent文件的链接;

4.选择本地存储路径,或者选定未完成的下载的续传;


5.等待下载完成;

6.下载者退出下载(之前下载者不停止上传)。




连通性如下:



·网站正常提供静态文件,并且启动客户端上的BitTorrent
helper(这里说官方的客户端程序);

·Tracker即时接收所有下载者信息,并且给每个下载者一份随机的peer列表。通过HTTP或HTTPS协议实现;


·下载者定时向Tracker登记,使之知道每个人的进度,并和那些直接连接上的peer互相进行数据的上传下载。这些连接遵循BitTorrent
peer协议,通过TCP协议进行通信。

·原始下载者只上传不下载,他拥有整个文件,所以向网络中传输完文件的所有部分是很必要的。在一些人气很旺的下载中,原始下载者经常可以在较短的时间后退出上传,因为许多下载已经完成,并且可能依然在运行(此时相当于替原始下载者接着提供上传)。




元信息文件和Tracker的回应信息都以一种简单高效可扩展的格式(Bencoding,B编码格式)传送。B编码过的信息就是字典和列表的嵌套(像在Python中一样),这些字典和列表包含字符串和整型数据。它的可扩展性是因为字典中存在被忽略的关键值(key),所以附加可选的关键值也可以在以后添加。




B编码的规则如下:



·字符串表示为前缀十进制的字符串长度加冒号再跟原字符串。


如4:spam就相当于'spam'。

·整型数据的表示是前面加'i'后面加'e'中间是十进制数,如i3e就相当于3,i-3e就是-3。整型数据没有长度限制。i-0e无效,所有以'i0'开头的除了代表0的i0e,其它都无效。


·列表编码为一个'l'开头,后面跟它所包含的项目(已经被编码过)最后加一个'e',比如
l4:spam4:eggse 就等于 ['spam', 'eggs'] 。

·字典编码为一个'd'开头,后面是关键值(key)及其对应值轮流出现,最后加一个'e'。


如:d3:cow3:moo4:spam4:eggse 相当于 {'cow': 'moo', 'spam':
'eggs'}

d4:spaml1:a1:bee 相当于 {'spam': ['a', 'b']}

关键值必须是处理过的字符串(用原始字符串编码的,而不是数字字母混合编码的)。




元信息文件就是B编码的有以下关键值的字典(括号里面的字是简译的关键值中文意思,不作为关键值一部分,后同):




announce(声明)



Tracker的URL。



info(信息)



此关键值对应一个包含以下关键值的字典:



关键值name对应一个字符串,代表默认的下载文件(或保存时目录)的名字。它是纯粹建议性的。




关键值piece
length(块长)对应文件分割成的块的字节数。出于传输需要,文件被分割成大小相等的块,除了最后一块可能会被文件尾截断而小一些(剩下的大小不足一个块长)。块长一般来说是2的权值,大部分设块长为256K即2的18次幂(BitTorrent官方版3.2版本以前的默认值是1M,2的20次幂)。




关键值pieces(块)对应一个字符串,此字符串长度是20的倍数。它可以再分成每20字节一段的多个字符串,分别对应块在相应索引中的SHA1校验码(hash)。




还有关键值length(长度)和files(文件),它们不能同时出现也不能都不出现。当length出现说明这个元信息文件只是提供单文件下载(the
single file case),否则说明是多文件下载(the
multi-file case),载到一个目录里。



单文件情况下,length对应文件长度的字节数。



多文件情况被看作是把许多单文件按文件列表中的顺序连成一个大文件下载,而关键值files就对应文件列表,是一个字典的列表,其中每个字典又包含以下关键值:




length(长度)



文件长度的字节数。



path(路径)



一个包含字符串的列表,字符串就是子目录名,最后一项的字符串就是文件本身的文件名。


(一个长度为零的length表单是错误的。)



在单文件情况下,关键值name是文件名;多文件情况下,它就成了目录名。




Tracker质询是双向的。Tracker通过HTTP协议的GET参数获得信息,然后返回一个B编码后的信息。尽管Tracker需要在自己的服务器端执行,但它运行流畅就像Apache的一个嵌入模块。




Tracker的GET请求有如下关键值:



info_hash



20字节长的SHA1验证码,就是元信息文件中的info值中分出来的字符串进行B编码以后的信息,是元信息文件的一个支链。这个值必须是自动转换的。




peer_id



一个20字节长的字符串,是每个用户开始新下载时随机生成的ID。这个值也必须是自动转换的。




ip



一个非强制性的参数(可有可无)给出peer所在的IP(或DNS主机名),一般是和Tracker同机器的原始下载者得到后用来散发文件。




port



监听端口,官方默认的是从6881端口开始试,如果端口被占用则依次向后推一个端口直到找到空闲端口,到6889端口没找到就放弃。




uploaded



目前总上传量,编码为十进制ASCII码。



downloaded



目前总下载量,编码为十进制ASCII码。



left



还要下载的字节数,编码为十进制ASCII码。这个数不能通过文件长度和已下载数出来的,因为文件可能是续传的,还可能有一些已经下载的数据不能通过完整性检查必须被重新下载。




event



这是个非强制性的关键值,有started,completed或stopped(或empty,等同于未运行)三种值。如果没有这个关键值,说明下载状态的声明也会从下载者那里定期发出。首次开始下载时发出started值,完成下载时发出completed。当文件完整后再开始,没有completed发出,下载者中止下载时发出stopped。




Tracker的回应也是B编码字典。如果Tracker回应中有关键值failure
reason(失败原因),则对应一个人易读懂的字符串信息,解释质询失败的原因,不需要其它关键值。否则,回应必须有两个关键值:interval(间隔)对应下载者定期发出请求的间隔秒数;peers,peers是个包含字典的列表,每个字典对应一个peer,里面包含关键值peer
id、ip和port,分别对应peer自选ID、IP地址或DNS主机名的字符串以及端口号。记住假如下载者发生一个意外事件或者想要更多的peer列表,下载者会不定期重发请求。




如果你想对元信息文件或者Tracker质询进行扩展,请与Bram
Cohen进行协调,确保所有扩展都兼容。



BitTorrent的peer协议通过TCP协议进行操作。它无须调节任何socket选项就可以高效运行。




peer之间的连接是对称的。两个方向收到的信息要看起来相同,数据可以流入任一方。




peer协议是说一个下载者从零开始下载,每得到元信息文件所描述的索引中的一个块且验证码一致,就向所有peer声明已得到此块。




连接的两个终端有2个状态指标,被阻塞与否,被关注与否,阻塞(choking)别人是表明在恢复通畅之前数据不再向对方发出。阻塞的推理和技术问题稍后会提到。




数据传输发生在一方关注对方且对方没有阻塞他的情况下。关注状态必须一致保持-如果一个没阻塞的peer没有别人需要的数据,别人对他就会失去关注,不论自己是不是被这个peer阻塞。完全执行这种条件可能有些狡猾,但这样的确可以让下载者知道哪些peer在阻塞消失后可以马上开始下载。




连接开始的时候,下载者状态是“被阻塞”和“不被关注”。




当数据传输时,下载者马上将好多份对块的请求排成队列,以获得较好的TCP表现(这叫“流水作业”)。另一方面,不能被马上写入TCP缓冲区的请求要在内存里排成队列,而不是在一个应用程序级的网络缓冲区里,一旦阻塞出现,丢弃所有这些请求。




peer连线协议包括一次握手跟着不断的数据流,数据流来自前缀长度的信息。握手以字符十九(十进制)开始,跟着是字符串'BitTorrent
protocol'。开头的字符是长度前缀的,希望其它新协议也能这样做以便区分。




所有送入协议的整型数据都编码为4字节高端字节序(four
bytes big-endian)。



头部数据之后是8个现在全部预留为0的字节,若果你想通过改变这8个预留字节以扩展协议,请与Bram
Cohen协调以保证所有扩展兼容。



然后是来自元信息文件中info值中B编码过的20字节的SHA1验证码(和info_hash向Tracker声明的值相同,但这里是原始值那里是引用)。如果双方的值不同,连接断开。一个例外是下载者想只用一个端口进行多个连接下载,它们会先从接入连接得到一个下载验证码,然后和列表里面的对照,相同的那个就回应。




下载验证码之后是20字节的peer
id,它包含在Tracker回应下载者的peer列表中,它是在peer向Tracker的请求中首先发出的。如果接受方peer
id不符合发送方希望,连接断开。



握手完毕。之后是长度前缀和信息轮流出现的数据流。零长度信息用来保持连接,被忽略。这种信息一般2分钟发一次,但是在等待数据期间超时很容易发生。




所有非保持连接用信息开头的字节给出类型,可能值如下:




·0-阻塞

·1-通畅

·2-被关注

·3-不被关注

·4-已有

·5-比特组

·6-请求

·7-块

·8-取消



“阻塞”、“通畅”、“被关注”和“不被关注”类信息没有荷载。




“比特组”类信息仅作为首信息发出。它负载一个比特组,下载者已有块的索引序号设同序号数位的值设为1,其它为0。开始下载时没有任何数据的下载者跳过“比特组”类信息。首字节高位到低位对应索引序号0-7,以此类推,第二字节对应索引序号8-15,等等。尾部的剩余的比特位设为0。




“已有”类信息负载一个数,即刚下载并核对完验证码的块对应的索引序号。




“请求”类信息包括包含一个索引序号,开始数和长度。后两者是偏移字节数。长度一般是2的权值除非被文件尾截断。现行一般是2的15次幂,并且关闭请求中长度大于2的17次幂的连接。




“取消”类信息负载和“请求”类信息有一样的负载。它通常在下载接近完成即“最后阶段(endgame
mode)”发出。当下载快要完成时,剩下几个块有都从同一个通信电路下载的趋向,这样会很慢。为了确保剩余块下载迅速,一旦还没有决定剩余块的下载请求向谁发出,先向所有他正在从对方下载数据的连接者发送要求所有剩余块的请求。为避免低效,每当一个块下载完成就向其他peer发出取消信息。




“块”类信息包含一个索引序号,开始数和块。记住它和“请求”类信息是相关的。当传输速度很慢或“阻塞”“通畅”类信息快速连续发出或两者同时发生,可能会载到一个不需要的块。




下载者下载块的顺序是随机的,防止下载者与其他Peer仅有相同的块子集或超集。




做出阻塞别人的决定有很多原因。TCP协议的挤塞控制(congestion
control)在即时向多连接发送信息的过程中表现极差。同时,阻塞的存在使下载者们能够用一报还一报式的算法来确保一致的下载速率。




下面描述的阻塞算法是目前基础的配置。重要的是所有新算法不光要在包含全部扩展算法的网络中运行良好,也要在主要包含这个基础算法的网络中运行良好。




一个优秀的阻塞算法有许多标准。它必须封锁一定上传数以获得良好的TCP表现,还要避免频繁的堵塞和通畅交替,即所谓“纤维化”(fibrillation)。它应该用数据交换报答给自己数据的peer。最后,它还应该偶尔尝试联一下与未连接过的peer,找出比现有连接好的连接,这叫做尝试性疏通(optimistic
unchoking)。



目前配置的阻塞算法避免纤维化的手段是每10秒转换被阻塞的peer。疏通4个自己关注且能从他们身上得到最高下载速率的peer,进行上传从而得到回报数据,这样同时就会封闭一些数据交换和上传数。有较高上传速率但是不被关注的peer被疏通,一旦这些peer开始下载者被关注,那些上传率最低的peer的就被阻塞。如果下载者有了完整的文件,他用自己的上传率而不是下载率来决定疏通谁的连接。




在任何一次尝试性疏通中都有一个peer被疏通,不管他的上传率如何(如果被关注,他会成为4个提供下载的peer之一)。被尝试性疏通的这种peer每30秒轮换一次。刚开始下载的peer会有大约其他人三倍的机会被尝试性疏通,这样他们就得到上传一个整块的机会(从而获取数据报答)。






部分术语对照:

protocol 协议

'Metainfo' file 元信息文件(.torrent文件)

'original' downloader “原始”下载者

key 关键值

Bencoding B编码格式

SHA1 Hash SHA1校验码

piece 块

single file case 单文件下载

multi-file case 多文件下载

choking 阻塞别人的行为

choked 被别人阻塞

interested 被关注

four bytes big-endian 四字节高端字节序

congestion control 挤塞控制(待定)

optimistic unchoking 尝试性疏通





基本证实我的猜想是比较正确的,就是关于路由表是随机给出的。关于详细协议请看上面。