發(fā)布時(shí)間:2024-01-24閱讀(15)

一.概述
Emule是建立在p2p技術(shù)上的文件共享軟件。它與傳統(tǒng)文件共享的區(qū)別是:
共享文件不是在集中的服務(wù)器上等待用戶端來(lái)下載,而是分散在所有參與者的硬盤上。所有參與者組成一個(gè)虛擬網(wǎng)絡(luò),每個(gè)用戶端都可以從這個(gè)虛擬網(wǎng)絡(luò)里的任何一個(gè)客戶端的機(jī)器里下載文件。同時(shí)每個(gè)客戶也可以把自己的文件共享給任何其他客戶。 在Emule體系里有一些服務(wù)器,不過(guò)這些服務(wù)器不再存放文件,而是存放這些共享文件的目錄或地址。每個(gè)用戶端從服務(wù)器處得到或搜索到共享文件的地址,然后自動(dòng)從別的客戶端處進(jìn)行下載,參與的客戶端越多,下載的速度越快。Emule建立于多點(diǎn)文件傳輸協(xié)議之上。一個(gè)Emule網(wǎng)絡(luò)由服務(wù)器端和客戶端兩部分組成。服務(wù)器端是客戶端連接的、為了搜索和查找可以下載用戶的橋梁。服務(wù)器列表像電話本一樣排列,客戶通過(guò)瀏覽它而獲取它需要的文件所有者的客戶端信息。在真正的文件下載過(guò)程中,沒(méi)有下載文件通過(guò)服務(wù)器端。其體系結(jié)構(gòu)如下圖所示:

圖1 Emule體系結(jié)構(gòu)
Searching:每一個(gè)客戶端連接到一個(gè)服務(wù)器作為他的主服務(wù)器。在連接時(shí),由客戶端告訴主服務(wù)器他share了那些文件,以及IP地址等其他信息。所以每一個(gè)服務(wù)器會(huì)記錄所有登陸到他服務(wù)器上的以上信息。在本服務(wù)器搜索時(shí),它會(huì)通過(guò)匹配記錄的已知以上信息把查找結(jié)果反饋給搜索的客戶端。當(dāng)一個(gè)客戶在搜索列表中選取了所需要的文件并開始下載后,Emule會(huì)記錄下這個(gè)文件的大小,文件名以及另一個(gè)根據(jù)文件內(nèi)容hash出的一個(gè)特殊值。Emule得到了這個(gè)信息后,會(huì)向所有添加的服務(wù)器發(fā)出請(qǐng)求,要求得到有相同hash值的文件。而服務(wù)器則返回持有這個(gè)文件的用戶信息。
Downloading:當(dāng)客戶端選擇了一個(gè)文件下載時(shí),它首先收集一個(gè)擁有該文檔的客戶端的列表。它會(huì)先行查詢主服務(wù)器所有登陸用戶他們是否擁有該文件。然后再連接和查選其他服務(wù)器的登陸用戶所擁有該文件的客戶端列表。一旦它找到擁有該文件的其他客戶端,它將請(qǐng)求每個(gè)客戶端發(fā)送這個(gè)文件的不同片。直至最后文件由這個(gè)不同的片組裝成一個(gè)完整的文件。 在查找到下載源(其他客戶端)后,下載就是客戶端和客戶端通過(guò)P2P進(jìn)行直接對(duì)話了。期間沒(méi)有數(shù)據(jù)流通過(guò)服務(wù)器。一個(gè)emule client可能會(huì)使用很多的tcp連接與其他client連接來(lái)彼此上傳或下載數(shù)據(jù).當(dāng)下載一個(gè)文件時(shí),client可能同時(shí)連接上許多不同的client,從它們那里獲得該文件的不同片段.即使一個(gè)client沒(méi)有下載完一個(gè)文件,他也能在下載的同時(shí)將已下載部分的片斷upload給其他client.emule中的server使用一個(gè)內(nèi)置的數(shù)據(jù)庫(kù)來(lái)存儲(chǔ)clients及其擁有文件的信息,它本身并不存放要下載或上傳的文件,而是對(duì)clients擁有的眾多文件起一個(gè)中央索引定位的作用.
二 .Client/Server TCP communication
2.1 Connection establishment
在Emule體系結(jié)構(gòu)中,一個(gè)client只能和一臺(tái)server建立連接,建立之后server賦予client一個(gè)client id,用于在以后的會(huì)話期間唯一的標(biāo)識(shí)這個(gè)client. Client/server的這一tcp連接在client的整個(gè)會(huì)話期間始終存在.Client id分high id 和low id兩種。當(dāng)一個(gè)client不能接受外來(lái)連接時(shí),它就被賦予一個(gè)low id.一種可能是client在NAT或者proxy server后面.如果一臺(tái)機(jī)器能讓其他client自由連接它本機(jī)的tcp port(default is 4662),那么它就被賦予一個(gè)high id.
High id的計(jì)算公式:
假設(shè)ip為x.y.z.w,
Id=x 2^8*y 2^16*z 2^24*w
而Low id 總是小于16777216(0x1000000)。
下面分別闡述High id和low id的client與server的連接過(guò)程:
High id連接過(guò)程:
Client建立一個(gè)和server的tcp連接,發(fā)送login message過(guò)去,server使用第二個(gè)tcp連接與client進(jìn)行handshake,其目的是為了檢驗(yàn)client是否有能力接受其他clients發(fā)起的連接.當(dāng)完成client-to-client握手之后,server關(guān)閉第二個(gè)連接,再發(fā)送個(gè)client一個(gè)id change 消息來(lái)完成client-server handshake.其過(guò)程如下圖所示:

圖2 high id login sequence
Low id連接過(guò)程:Client同樣與server建立連接,但是當(dāng)server與client建立連接時(shí)將失敗,通常發(fā)回給client一個(gè)消息,形如”Waring you have a lowed.Please review your network config”.最后server仍舊發(fā)送一個(gè)id change message.如下圖所示:

圖3 low id login sequence
注意,Emule中的server配置有兩個(gè)限制:hard limit和soft limit;
其中Hard limit >= soft limit.當(dāng)連接一個(gè)server的clients 數(shù)達(dá)到soft limit時(shí),server停止接受low id client的連接;當(dāng)達(dá)到hard limits時(shí),server停止對(duì)任何client的連接.此時(shí)的連接過(guò)程如下圖所示:

圖 4 Reject Session sequence
2.2Connection starup message exchange:
當(dāng)cs連接成功建立之后,client與server彼此交換一些setup message.client向server提供一個(gè)list,記錄了自己shared的文件,然后要求更新server list.于是server發(fā)回它的狀態(tài)和版本信息,以及自己維護(hù)的眾所周知的server list.最后client就會(huì)要求下載某些文件,此時(shí)server就會(huì)查找哪些其他的clients擁有這個(gè)被請(qǐng)求的文件,然后將這些clients的列表發(fā)回給請(qǐng)求的client.如下圖:

圖3 Connection starup sequence
Callback 機(jī)制:
設(shè)計(jì)這一機(jī)制的目的在于克服low id client不能接受外來(lái)連接的缺點(diǎn)。其實(shí)現(xiàn)原理很簡(jiǎn)單:假設(shè)a和b連接上同一個(gè)server,a需要一個(gè)文件,這個(gè)文件存放在b上,但b擁有一個(gè)low id.于是a發(fā)送一個(gè)callback request給server,要求server通知b主動(dòng)連接a..server于是給b發(fā)送一個(gè)callback request,為其提供了a的ip和port,之后b就能與a建立連接,而不需要server的干預(yù)了.

圖4 callback sequence
三. Client/Server UDP communication
3.1 Server keep alive and status information
Client周期性的對(duì)自己server list上的server進(jìn)行狀態(tài)檢查.這是通過(guò)client發(fā)送UDP server status request消息和UDP server description request這兩個(gè)消息來(lái)完成的. 其中server status request中包括一個(gè)隨機(jī)數(shù).這個(gè)數(shù)在server的reply中被回射.倘若回射值與原來(lái)的不一致,則server的reply中的信息被丟棄.client維護(hù)一個(gè)計(jì)數(shù)器,每次status request發(fā)送出去時(shí)計(jì)數(shù)器加一,從server收到的任何消息都重置這個(gè)計(jì)數(shù)器.當(dāng)這個(gè)計(jì)數(shù)器的值達(dá)到一個(gè)預(yù)先配置的上限時(shí),server被認(rèn)為不可用,從client的server list中刪除. Server statusrequest的reply包括當(dāng)前用戶數(shù)和server中索引的文件以及server的soft/hard
Limits.而Server description reply包括server name和一個(gè)短的描述性字符串。整個(gè)過(guò)程如下圖所示:

.
圖5 UDP keep alive sequence
3.2 Enhanced File search
Emule的client能使用UDP服務(wù)來(lái)增強(qiáng)其文件搜索功能。當(dāng)一個(gè)client試圖下載一個(gè)文件,但是他得到的sources數(shù)目小于一個(gè)可配置的值(默認(rèn)是100)的時(shí)候,它就會(huì)周期性的向自己server list里的所有server發(fā)送UDP get sources packet來(lái)試圖找到更多的擁有此文件的sources。
四.Client To Client TCP Communication
在client與server成功建立連接,并且從server那里取得擁有自己想要的文件的sources信息之后,clinet就需要與source列表中其他的client交互,即分別與這些source都建立起一個(gè)tcp 連接.當(dāng)一個(gè)連接上在某個(gè)時(shí)間段內(nèi)(默認(rèn)是40秒)之內(nèi)套接字沒(méi)有事件到來(lái)(沒(méi)有讀或?qū)?或者任何一個(gè)client端關(guān)閉了連接時(shí),該tcp連接就失效.
4.1 Initial handshake
這種握手是對(duì)稱的:兩端都向?qū)Ψ桨l(fā)送同樣的信息.信息中包括identification,version和capabilities information.發(fā)送的信息有兩種類型,一種是hello message,這實(shí)際上是eDonkey協(xié)議的一部分,另外一種是Emule info message,這部分是Emule協(xié)議自己特有的部分。握手過(guò)程如圖:

圖6 eMule client initial handshake
4.2 The Credit System
設(shè)計(jì)Credit system的目的是為了鼓勵(lì)用戶彼此共享更多的文件。當(dāng)一個(gè)client為他的peer上傳文件時(shí),正在下載的peer根據(jù)接收到的數(shù)據(jù)量來(lái)更新credit值.這個(gè)credit并不是全局的.一個(gè)特定的傳輸過(guò)程對(duì)應(yīng)一個(gè)特定的credit值,這個(gè)值被正在下載的client保存,只有當(dāng)為這個(gè)client提供上傳的peer轉(zhuǎn)而要求從client上面下載文件的時(shí)候,這個(gè)credit才起作用.
Credit取下列值的最小值:
1. uploaded_total*2/downloaded_total
當(dāng)downloaded_total為0時(shí),整個(gè)表達(dá)式設(shè)為10.
2. sqrt(uploaded_total 2):
當(dāng)uploaded_total< 1 MB 時(shí),這個(gè)表達(dá)式設(shè)為1.
注意,credit的取值范圍:1<=credit<=10.
4.3 Requesting files
Client A 發(fā)送一個(gè)file request message,其后緊跟一個(gè)requested file id message.Client B
對(duì)于這兩個(gè)消息的回復(fù)如下:前者以一個(gè)file request answer消息回復(fù),后者以一個(gè)file status message作為應(yīng)答.該協(xié)議還可被擴(kuò)展為:在這個(gè)消息序列中增添兩條新的消息:source request和source answer。通過(guò)這兩條消息,就能把B的sources列表發(fā)送給A,同時(shí),B也能把自己已經(jīng)下載了的文件片斷發(fā)送給A。如果B并沒(méi)有A所請(qǐng)求的文件,B就不發(fā)送file request answer消息,取而代之的是file not found message。

圖7 File request failure
4.4 Queue Management
假如Client A向Client B請(qǐng)求一個(gè)文件,B擁有,但是其上傳隊(duì)列非空,這意味著當(dāng)前存在其他client已經(jīng)與Client B握手完畢并正在下載文件,于是B將A加入到它的upload隊(duì)列,并返回一個(gè)queue ranking message,這條消息內(nèi)包含了A在B的upload隊(duì)列中的位置.
對(duì)于upload文件的client B來(lái)說(shuō),它自己維護(hù)一個(gè)upload隊(duì)列.在隊(duì)列中每個(gè)client的優(yōu)先級(jí)以client在隊(duì)列中的逗留時(shí)間及一個(gè)優(yōu)先級(jí)變量來(lái)決定.在隊(duì)列頭的client具有最高的score.score的計(jì)算公式:
Score=rating*seconds_in_the_queue/100.
假如該client被定義為friend,則socre為無(wú)窮大.Rating一般被初始化為100.
Rating的變動(dòng)取決于下列情況:
1. 正在下載用戶的 credit值(1~10);
2. 上傳文件的優(yōu)先級(jí)(0.2~1.8)
當(dāng)隊(duì)列中一個(gè)client的score超過(guò)了某個(gè)正在下載的client時(shí),正在下載文件
的client就被搶占。為了避免一個(gè)client剛剛開始下載就被別的client所搶占,emule將一個(gè)剛開始下載的client的rating設(shè)置為200,并維持15分鐘. 當(dāng)a到達(dá)b的upload隊(duì)列隊(duì)首時(shí),b連接a,進(jìn)行handshake等初始化工作,然后發(fā)送一個(gè)accept upload request message.此時(shí)a有兩種選擇:或者發(fā)送一個(gè)request parts message來(lái)開始下載文件,或者選擇取消(此時(shí)它可能已經(jīng)在其他sources處下載到了想要的文件片斷).
4.5 Data Transfer
當(dāng)一個(gè)File request answer消息被發(fā)送之后,文件塊的傳輸就開始了。試圖下載的Client A發(fā)送一個(gè)start upload request,而Client B以accept upload request回復(fù)。然后A就開始逐一請(qǐng)求文件塊,而B開始發(fā)送A所請(qǐng)求的塊。

圖 8 文件傳輸
4.6 塊的選擇策略
在Emule中,每個(gè)文件被分成大小為9.28MB的一系列塊,每個(gè)塊又被分成180kb大小的子片斷。下載時(shí)使用下面的片斷選擇策略:
1.Sources之間擁有的最少的片斷應(yīng)該盡可能快的下載,這樣一旦下載結(jié)束,該client就能成為一個(gè)新的可用的source。
2.那些用來(lái)預(yù)覽的子片斷(比如first,last塊),或者用于文件校驗(yàn)的塊(如movie,
mp3)。
3.一個(gè)塊中如果有部分子片斷被下載,那么其他的子片斷應(yīng)該盡可能快的被下載,而不是又去挑選一個(gè)新的塊來(lái)下載
4.7 查看共享文件及文件夾
兩個(gè)client之間通過(guò)消息傳遞來(lái)查看彼此共享的文件和文件夾。對(duì)于查看文件,使用view shared files和view shared files answer這對(duì)消息來(lái)完成。當(dāng)一個(gè)client試圖隱藏自己共享的文件列表時(shí),它發(fā)送的view shared file answer消息中包含0個(gè)文件,而不是采取發(fā)送一個(gè)denied消息通知對(duì)方這種方式。如圖所示:

圖 9 View shared files
而對(duì)于查看文件夾來(lái)說(shuō),client向另一端發(fā)請(qǐng)求以查看共享的文件夾列表,然后收到另一端回復(fù)過(guò)來(lái)的共享文件夾列表。然后對(duì)于該回復(fù)消息包含的列表中的每一個(gè)文件夾,都發(fā)送一個(gè)view shared folder content消息過(guò)去。這個(gè)消息的回復(fù)是一個(gè)content list。

圖10 View shared folders
五.Client To Client UDP Communication
在Emule中,client使用UDP協(xié)議周期性地查詢自己在另一端的client的隊(duì)列中的位置。其實(shí)現(xiàn)方法是用一種簡(jiǎn)單的“請(qǐng)求-回復(fù)”機(jī)制,以一個(gè)Re-ask file 消息來(lái)初始化。對(duì)于這一消息,有三種可能的回復(fù):
1. Queue rank:表明該client在其sender隊(duì)列中的位置;
2. Queue Full:表明sender的隊(duì)列已滿;
3. File not found:sender并沒(méi)有該client請(qǐng)求的文件;
Re-ask消息以20分鐘一次的間隔發(fā)送往那些已經(jīng)將它加入到下載隊(duì)列的所有sender去。

圖 11 Re-ask file message
六.Message Encoding
所有的消息都是以little-endian方式編碼.
所有的消息都具有一個(gè)6字節(jié)的頭部:
頭部結(jié)構(gòu)如下:
1字節(jié)的協(xié)議id:edonkey為0xe3,emule為0xc5;
4字節(jié)的消息大小,該大小不包含頭部,假如消息內(nèi)不含任何負(fù)荷(payload),則該字段為0;
1字節(jié)的消息類型字段,是一個(gè)獨(dú)一無(wú)二的消息id.
Message tag:
Tags是一種形如(Type,length,value)的結(jié)構(gòu),用于給emule 中的各種消息追加一些可選的額外信息.
每個(gè)tag有4個(gè)域:
1. type:1個(gè)字節(jié)的整數(shù)
2. name:可以是變長(zhǎng)的字符串或者1個(gè)字節(jié)的整數(shù);
3. value:可以是4字節(jié)整數(shù)或者4字節(jié)浮點(diǎn)數(shù)或者是可變長(zhǎng)的字符串
4. 特別字段域:1字節(jié)的整數(shù)
希望看了這些介紹之后,大家能對(duì)Emul的工作原理有最基本的認(rèn)識(shí),謝謝。

歡迎分享轉(zhuǎn)載→http://m.avcorse.com/read-215381.html
Copyright ? 2024 有趣生活 All Rights Reserve吉ICP備19000289號(hào)-5 TXT地圖HTML地圖XML地圖