4 客户端到客户端的TCP交流
在eMule客户端注册到服务器和向服务器查询文件和源之后,为了下载文件,eMule客户端需要联系其它客户端。为每对[文件,客户端]创建一个专用的TCP连接。当特定的周期内(默认40秒)没有任何socket活动或者对方已经关闭了这个连接,那么这个连接就会关闭。 为了提供合理的下载速率,直到可能提供给它(和所有其它下载的客户端)至少最小允许速率(当前的硬编码常量设置为2.4k/s),eMule才允许客户端开始下载文件。
4.1 初始的握手
初始的握手是对称的 - 双方都相互发送相同的信息给对方。客户端交换双方的信息,信息包括身份认证、版本和容量等。参与的有两种类型消息 - Hello消息(6.4.1节)和eMule信息消息(6.5.1节),第一种是eDonkey的一部分,兼容eDonkey客户端,第二种是eMule独有的扩展客户端协议的一部分。图4.1图解了两个eMule客户端之间的握手。在扩展信息中包含的有UDP消息交换、安全身份证明和源交换能力。
16
4.2 安全的用户身份认证
1.4节简单解释了关于用户ID和用户假冒其它用户的动机。安全用户认证是eMule扩展的一部分。如果客户端支持安全认证,就会在初始化握手之后立即执行。安全认证的目的是防止用户冒名顶替。当实施安全认证时,执行以下步骤:
1.在初始化握手中,B客户端指明它支持和希望使用安全认证。
2.通过发送安全认证消息(见6.5.8)来回应,指明A是否需要B的公匙,也包含了B发出的4字节的询问。
3.如果A指明它需要B的公匙,B就将它的公匙发送给A(6.5.9节)。
4.B发送一个签名消息(6.5.10节),签名消息是用发送过来的询问和额外的双字节创建的,双字节要么是A的IP地址如果B是低ID,要么是B的ID如果它有高ID。图4.2演示了这个顺序。
4.2.1 信用系统
本节简要地描述了客户端的信用系统。信用系统的目的是鼓励用户共享文件。当客户端上传文件给它的对方,下载的客户端就根据数据传输的数量来更新它的信用。注意,信用系统不是全局的 - 传输的信用被下载的客户端局部保存,只有当上传的客户端(获得信用的那个)要求从这个特定的客户端下载时,信用才会被考虑。信用是用下面最小值计算的:
1. 上传的总量 * 2 / 下载的总量
当下载的总量是零时,这个表达式估值是10
17
2. 上传的总量 + 2 的和开方
当上传的总量小于1MB,这个表达式估值是1
上传/下载数量是以M为单位计算。任何情况下,信用不会高过10或者低于1。
4.3 请求文件
正如已经提到的一样,每对[客户端,文件]都创建一个独立的连接。在连接建立之后,客户端立即发送几个关于它希望下载的文件的请求消息。4.3节描述了一个典型的、成功的情景。
4.3.1 基本消息交换
基本消息交换是由四个消息构成:A发送一个文件请求消息,立即跟着的是请求文件ID消息(6.4.17节)。B用文件请求回答回应文件请求,用文件状态(6.4.18节)来回应请求文件的ID消息。我找不到任何理由来把这些发送过来的消息中的信息分成四个消息,它可以容易地用两个消息(请求和回应)来处理。
扩展协议增加两个消息到这个顺序中,源请求消息(6.5.6节)和源回应消息(6.5.7节)。用这个扩展来传递B的源(假定B当前下载着文件)到A中。详细阐述就是,在它能发送文件块给其它客户端之前B完成下载一个文件是没有任何要求的,B可以发送任何它已经完成下载的文件块,甚至当它只是用文件的一小块。
18
4.3.2 没找到文件的情景
当A向B请求一个文件,但是B的共享文件列表中没有这个文件。B忽略这个文件请求回应消息,在请求文件ID消息之后立即发送一个没有文件消息(6.4.16节),如图4.4所演示。
4.3.3 加入上传队列
当B有被请求的文件但是它上传队列不为空,意味着有正在下载文件的客户端,也可能有客户端在上传列表中,在这种情况下,A和B执行满握手,如图4.3所述,但是当A请求B开始下载文件时,B把A加入到它的上传队列中,回应一个队列等级消息,这个消息包含A在B地上传队列中的位置。图4.5演示了这个顺序。
19
4.3.4 上传对列管理
对每个上传的文件,客户端维护着一个上传优先级队列。队列中的每个客户端的优先级是以客户端在队列中的时间和优先级修正为基础计算的。位于队列头部的客户端有一个最高级别的分数。分数是用以下的方程式计算的:分数 = (等级 * 队列中的秒数)/100或者无穷大,如果下载的客户端被定义为朋友。初始化的等级值是100,除开禁止的用户是0等级(这样阻止达到队列的前面)外。等级可以被下载客户端的信用(范围1-10)或上传文件优先级(0.2-1.8)修改,上传文件优先级是由上传客户端设置的。当一个客户端的分数比其它的客户端高时,它就开始下载文件。客户端可以继续下载文件直到产生以下任一个条件: 1.用户关闭了上传客户端。
2.下载的客户端得到了它所需文件的所有部分。
3.下载的客户端给其它拥有比它更高优先级的客户端抢占。
为了允许一个刚刚开始的客户端在它被抢占之前可以得到几M的数据,eMule在客户端下载的前15钟内增加初始等级到200。
4.3.5 到达上传队列的顶部
20