分享
 
 
 

Tracker 服务器源码分析之三:HTTPHandler 类

王朝other·作者佚名  2006-01-30
窄屏简体版  字體: |||超大  

Tracker 服务器源码分析之三:HTTPHandler 类

作者:小马哥

日期:2004-6-7

本篇文章分析 HTTPHandler类,它在 HTTPHandler.py 文件中。

上一篇我们讲到, RawServer 只负责网络 I/O,也就是从网络上读取和发送数据,至于读到的数据如何分析,以及应该发送什么样的数据,则交给 Handler 类来处理。如果是用 c++ 来实现的话,那么 Handler 应该是一个接口类(提供几个虚函数作为接口),但是 python 动态语言的特性,并不需要专门定义这么一个接口类,所以实际上并没有 Handler 这么一个类。任何一个提供了以下成员函数的类,都可以作为一个 Handler 类来与 RawServer 配合,它们是:

external_connection_made():在建立新的连接的时候被调用

data_came_in():连接上有数据可读的时候被调用

connection_flushed():当在某个连接上发送完数据之后被调用

HTTPHandler 就是这样一个 Handler 类,它具备以上接口。

HTTPHandler 代码很少,因为它把主要工作又交给 HTTPConnection 了。

我们看 HTTPHandler 类的这几个函数:

l external_connection_made():

每当新来一个连接的时候,就创建一个 HTTPConnection 类。

l data_came_in():

当连接上有数据可读的时候,调用 HTTPConnection::data_came_in()。我们接下去看HTTPConnection::data_came_in()。

我们知道,BT client端与 tracker服务器之间是通过tracke HTTP 协议来进行通信的。HTTP协议分为请求(request)和响应(response),具体的协议请看相关的 RFC 文档。我这里简单讲一下。

对 tracke 服务器来说,它读到的数据是 client 端的HTTP 请求。

HTTP请求以行为单位,行的结束符是“回车换行”,也就是 ascii 字符 “\r”和“\n”。

第一行是请求的 URL,例如:

GET /announce?ip=aaaaa;port=bbbbbbb HTTP/1.0

这行数据被空格分为三部分,

第一部分GET表示命令,其它命令还有POST、HEAD等等,常用的就是GET了。

第二部分是请求的URL,这里是 /announce?ip=aaaaa;port=bbbbbbb。如果是普通的上网浏览网页,那么URL 就是我们要看的网页在该web服务器上的相对路径。但是,这里的URL仅仅是交互信息的一种方式,client 端把要报告给 tracker 的信息,放在URL中,例子里面是 ip 和 port,更详细的信息请看“BT协议规范”中 tracker 协议部分。

第三部分是HTTP协议的版本号,在程序中忽略。

接下来的每一行,都是HTTP协议的消息头部分,例如:

Host:www.sina.com.cn

Accept-encoding:gzip

通过消息头,tracker服务器可以知道 client端的一些信息,这其中比较重要的就是 Accept-encoding,如果是 gzip ,那么说明 client 可以对 gzip 格式的数据进行解压,那么tracker服务器就可以考虑用 gzip 把响应数据压缩之后再传回去,以减少网络流量。我们可以在代码中看到相应的处理。

在消息头的最后,是一个空行,表示消息头结束了。对GET和HEAD命令来说,消息头的结束,也就意味着整个client端的请求结束了。而对 POST 命令来说,可能后面还跟着其它数据。由于我们的 tracker服务器只接受 GET 和 HEAD 命令,所以在协议处理过程中,如果遇到空行,那么就表示处理结束。

HTTPConnection::data_came_in() 用一个循环来进行协议分析:

首先是寻找行结束符号:

i = self.buf.index('\n')

(我认为仅仅找 “\n”并不严谨,应该找 “\r\n”这个序列)。

如果没有找到,那么 index() 函数会抛出一个异常,而异常的处理是返回 True,表示数据不够,需要继续读数据。

如果找到了,那么 i 之前的字符串就是完整的一行。于是调用协议处理函数,代码是:

self.next_func = self.next_func(val)

在 HTTPConnection 的初始化的时候,有这么一行代码:

self.next_func = self.read_type

next_func 是用来保存协议处理函数的,所以,第一个被调用的协议处理函数就是 read_type()。它用来分析client端请求的第一行。在 read_type() 的最后,我们看到:

return self.read_header

这样,在下一次调用 next_func 的时候,就是调用 read_header()了,也就是对 HTTP 协议的消息头进行分析。

下面先看 read_type(),

它首先把 GET 命令中的 URL 部分保存到 self.path中,因为这是 client端最关键的信息,后面要用到。

然后检查一下是否是GET或者HEAD命令,如果不是,那么说明数据有错误。返回None,否则return self.read_header

接下来我们看read_header(),

这其中,最重要的就是对空行的处理,因为前面说了,空行表示协议分析结束。

在检查完 client 端是否支持 gzip 编码之后,调用:

r = self.handler.getfunc(self, self.path, self.headers)

通过一层层往后追查,发现 getfunc() 实际是 Tracker::get(),也就是说,真正对 client 端发来的请求进行分析,以及决定如何响应,是由 Tracker 来决定的。是的,这个 Tracker 在我们tracker 服务器源码分析系列的第一篇文章中就已经看到了。在创建 RawServer 之后,马上就创建了一个 Tracker 对象。所以,要了解 tracker 服务器到底是如何工作的,需要我们深入进去分析 Tracker 类,那就是我们下一篇文章的工作了。

在调用完 Tracker::get() 之后,返回的是决定响应给 client 端的数据,

if r is not None:

self.answer(r)

最后,调用 answer() 来把这些数据发送给 client 端。

对 answer() 的分析,我们在下一篇分析 Tracker类的文章中一并讲解。

l connection_flushed():

tracker服务器用的是非阻塞的网络 I/O ,所以不能保证在一次发送数据的操作中,把要发送的数据全部发送出去。

这个函数,检查在某个连接上需要发送的数据,是否已经全部被发送出去了,如果是的话,那么关闭这个连接的发送端。(为什么仅仅关闭发送端,而不是完全关闭这个连接了?疑惑)。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有