基於P2P的區域網多執行緒共享軟體設計論文

來源:才華庫 3.09W

1 系統概述

基於P2P的區域網多執行緒共享軟體設計論文

本系統的主要功能其一,區域網下的檔案P2P共享,這裡包括檔案的傳輸和檔案列表的傳輸;其二,區域網下使用者的P2P心跳檢測。系統的特點是多執行緒多工同步。

2 設計思想

下面將從兩個大模組來介紹設計思路,首先是檔案的收發,然後是檔案列表的收發和心跳模組,如圖1所示。

2.1 檔案收發模組

檔案的收發是resource-shaie最基本的功能,也是最核心的功能。

2.1.1 有關檔案收發的Socket的分類

因為這裡採用的是TCP協議,所以在程式中,大體上存在於3組Socket,與檔案收發有關,一組Socket是welcomesocket,用於監聽連線的到來,並Accept;另一組Socket,是資料傳輸的Socket,來自於welcomesocket的accept(),用於send檔案資料給對等方,姑且稱作sendsocket;最後一組Socket也是資料傳輸的socket,通過connect()對等方的welcomesocket得到,與上面那個sendsocket是直接相連的,只是因為所面對的物件不同,對於當前對等方,因為這個Socket的用於recover檔案,姑且稱作recvsocket。

可以這樣理解,對於一個對等方來說,sendsocket就只send(),recvsocket就只recover ()。之所以這樣分開,是為了方便管理,降低耦合度,使得兩個對等方之間的所直接相連的一對sendsocket和recvsocket在一個檔案任務中維繫關係,也就是說,一對socket,在同一時間只共同執行一個任務,一邊是發和一邊是收。然而,如果全在一個Socket中send和recv,就會變得很亂,一個socket就可能牽連多個任務,一個socket出了問題,可能幾個任務的收發都會失敗。

下面舉一個例子來具體說明為什麼要這樣分類。

假使現在有兩個人,hana和alice。考慮hana從alice下載一個檔案的情況,在不考慮上傳操作的時候,hana是主動的,alice是下載方,所以首先hana會connectalice的welcomesocket,而對於alice而言,她的welcomesocket一直在等待hana的接入,hana—旦發起連線她就會accept。接著,hana通過connect得到的socket就是所謂的recvsocket,而這個socket相對於alice,就是alice的sendsocket,她將從這個socket裡接收資料,但是目前還不行,因為alice並不知道hana的要求是什麼,所以這裡需要向alice傳送一個請求,同樣是通過recvsocket。對於alice而言,假使已經從welcome socket accept到了一個sendsocket,那麼首先要獲取請求,她需要先對sendsocket執行一次recv請求的操作。

到這裡,請求完成了,接下來,hana的recvsocket就不斷接收檔案資料,alice的sendsocket不斷髮送檔案資料。反過來,假使alice想從hana那裡下載東西,因為二人都有上述3組Socket,所以很容易實現。實際上,想實現上傳功能也可以用完全一樣的邏輯體系,只需要從後者傳送一個特殊指令,使得前者傳送一個下載請求給後者即可,如圖2所示。

2.1.2 檔案請求的監聽和連線

上面討論的是純粹的傳輸一個檔案的情況,下面內容逐漸複雜。

還是上面的例子,假設現在需要支援多工的模式,也就是說,alice不僅僅要向hana—個人傳送一個檔案,而是將會向很多人傳送檔案,並且對於每個人,還不只是一個檔案。

那麼,alice可以開多個welcomesocket去listen,每一個welcomesocket監聽n個使用者,接著通過accept返回每一個檔案的sendsocket,這樣一來,就等於說和每一個終端都建立起了多個傳送通道,每個傳送通道傳送一個檔案,也就是一個任務。

現在問題是到底需要幾個這樣的welcomesocket?當然,可以只開一個welcome,全靠一個welcomesocket監聽(使用者數量)*(每個使用者的檔案請求數量)數量的請求。但在實際設計中,使用了多個埠建立了多個welcomesocket,讓每一個welcomesocket對於每一個訪問他的終端而言,在單個任務執行的過程中,只能有一個檔案的請求。這樣一來,每一個welcomesocket的最大併發連線數就一定是使用者的總數量,而welcomesocket的數量就是由alice能夠同時向一個終端send幾個檔案決定的。

也就是說,hana在前一個下載任務執行完關閉recvsocket以前,不能向同一個welcomesocket再一次發起connect,(當然因為welcomesocket的實體是在alice那邊,所以hana在這裡,實際上禁用了對於此welcomesocket的connect操作)這樣做的目的是為了限制對於同一個使用者的最大下載量。

所以,對於hana來說,假如她要從alice或者其他人那裡下載多個檔案,這就要求hana去connect那些使用者的多個welcomesocket,在connect中傳入的地址可能包涵每一個物件的IP和每一個傳輸port,所以hana的recvsocket最多可以和ip_num*port_num個數的sendsocket建立連線。(ip_num代表傳送端數量,一個ip—臺使用者,port_num代表在一個ip下對於單使用者支援的最大傳輸任務數量,那麼,對於alice而言,

她最多同樣可以同時傳輸ip_num*port_num個任務)而在每一次任務完成之後,hana都會關閉掉那個任務的recvsocket,並且將這個任務所對應的welcomesocket的禁用狀態解除;與之對應的,alice在傳送完之後,也會將sendsocket關閉。

通過圖3來看這種情況,假使這次alice不僅要給hana傳送檔案,還要給自己的母親傳送檔案,對於hana或者alice的母親而言,最多同時從alice這裡下載3個檔案。

2.2 檔案列表收發和心跳模組

2.2.1 動態心跳檢測

前面說了P2P的檔案傳輸機制,還講了多工多使用者的情況,現在來說一下這個系統中的另一個很重要的機制,心跳機制。通過傳送心跳資訊和接收心跳,用來感知在區域網中,有哪些對等方是存在的,雙方的心跳包中有少量的資料,一般而言包含使用者的資訊,比如使用者名稱,終端系統資訊之類的。只有知道哪些對等方式存在的,才能進一步的儲存這些對等檔案通訊中的有用資訊,(可能包括這個使用者的檔案列表,這個使用者的各個welcomesocket的地址,等),最後根據這些資訊才能真正地實現檔案通訊。

還是上面的那個例子,考慮了這樣情況,hana先上線了,過了一段時間alice才上線。那麼在alice上線的那一瞬間,如何使得兩人都知道對方上線了呢,準確地說,是通過P2P軟體上線。這就好比兩臺機器都上了網,並且都登上了QQ,但QQ判斷是否上線,僅僅是有沒有在QQ上線,而不是在SKYPE上線了,所以我們應該有一套自己的機制,這就是要介紹的心跳機制。

在這裡,機制是這樣實現的:不管對於hana或者alice,她們在上線的時候首先都會進行廣播式的連線嘗試,廣播物件是子網網段下所有的IP地址。其次,她們還會單獨為心跳建立一個welcomesocket,開一個監聽的執行緒專門用於監聽新上線使用者的connect請求。在這裡,判斷是否線上的邏輯是 “收到某人的心跳包,就表示某人目前線上”。

在結合例子講解之前,先討論心跳機制中的socket分類。心跳的welcomesocket和檔案傳輸的那個welcomesocket沒有什麼性質上的區別,無非就是擁有自己獨特的埠號而已。但是,心跳的收發是沒有sendsocket和recvsocket的這種概念的,只有一個heartsocket,這個socket是一個專門用於心跳收發的長連線socket,他一直存在,不會被close的.,所以會被長期儲存,這裡要和之前說的用於檔案傳輸的sendsocket和recvsocket區分,他們有很大的差異,首先,檔案傳輸的send和recvsocket是不會長期儲存的,一般只是一些函式中的區域性變數,因為他經常改變,他傳完一個任務就關閉了,下一次又重新生成,所以檔案傳輸中這些收發socket屬於短連結的socket,其次,在heartsocket中,傳送和接收都是通過這一個socket。

舉—個例子,假設hana首先上線,她先開啟了心跳wel-comesocket的監聽,這時候,alice並沒有上線,所以有反饋,並且hana對子網內中所有ip的connect的嘗試也都失敗了。在這之後,alice上線了,首先alice的廣播式connect嘗試,成功激活了hana的welcomesocket的迴圈accept,成功連線之後,alice通過return的heartsocket,向hana傳送一個心跳包,hana在accept之後會立馬recv這個心跳包,hana接收到心跳包之後,就認為alice目前處於線上了,他也可以通過心跳包裡的資訊知道來自於這個ip的人的名字叫alice,接著她要做的是就是把這個heartsocket儲存好,準備下一次收發心跳包。那麼流程到此,hana已經知道alice的存在了,但是alice卻還並不知道hana的存在,因為她還沒有接受到hana的心跳包。所以,hana在接收到alice的心跳包之後,儲存了相關資訊後,她還會通過這個heartsocket傳送一個心跳包給alice,而對於alice而言,在她傳送完心跳包之後,她會馬上recv對方的心跳包,這樣一來,就使得alice也知道了hana的存在了。

在相互都知道對方的存在之後,大家通過這同一個heartsocket相互發送和接收心跳包了,每接收一個心跳包就代表目前對方是存在的,一旦接受超時,那麼就代表對方下線了,這樣就可以動態監測對方是否已經下線,如圖4所示。

2.2.2 檔案列表的收發

下面來討論文件列表的收發。這個可以和之前的檔案收發關聯起來,因為檔案列表在一般情況下是不會有變動的,故而沒有必要一直重複接受對方的檔案列表,僅僅是在第一次的時候和使用者自己認為需要更新的時候再去接收新的檔案列表。所以,可以知道的是,檔案列表的socket也是一種短連線的socket,用完了關閉就行了,需要的時候再connect對方的welcomesocket。

同樣,檔案列表的傳輸是雙向的,所以在設計中,基本上和之前說到的檔案傳輸機制如出一轍,也是3個socket,welcomesocket,recvsocket,sendsocket。只不過,請求檔案列表的那個人不需要傳送那個所謂“檔案請求”而已,connect之後,直接從recvsocket中接收就可以了。

3 類設計思想

由於篇幅有限,只能做一下思想的概述。根據需求,類設計包括:user,myself_user,task,task_manager。結合物件導向的思想,其中有兩種類別,一種跟“使用者”有關,另一種跟“任務”有關。

在設計中,何為“使用者”,何為“任務”?具體概念,必須先弄清楚。使用者這個物件,指的是區域網中的對等方,也就是P2P中的peer,可以是自己的電腦,也可以是別人的電腦,這裡還有一個myself_user的類,這個物件指的是本機使用者,並且是user的子類。任務則是指,對於自己電腦而言,每一個下載任務的例項,也就是說,你每一次向別的對等方請求一個檔案,都會產生一個下載任務。

3.1 使用者有關類

User:使用者類的主要職能是儲存peer的資訊,包括ip、名字、welcomesocket的地址、heartsocket等。

Myself_user:作為user的子類,除了儲存了普通使用者應有的資訊之外,還要儲存一些自身獨有的資訊,以及為其他peer提供一些服務,包括有檔案列表的傳輸服務,檔案的傳輸服務。

世界就是圖5這樣的,進來的箭頭表示請求,從自己出去的箭頭表示反饋(也可以稱作“提供”)

user_manager:這個類字面上就可以理解是使用者管理器,主要職能就是動態監測使用者狀態。通過收發心跳包的手段來嗅探使用者狀態,然後更新使用者管理器中的使用者組,將不存在的刪除,新上線的新增。除此之外,他也和myself_user是相輔相成的,他初始化myself_user,並開啟myself_user的服務。所以在實際應用的時候,只需初始化user_manager,他就可以自己去初始化myself_user了。除此之外,檔案列表的請求實際上也是從user_manager這裡傳送出去的,並且它也負責接受檔案列表並更新某個user中所儲存的檔案列表。

3.2 任務有關類

Task:這個類代表了一個下載的任務資訊的物件,包括任務名、物件ip、大小、已完成%,等。值得注意的是,它不僅能儲存資訊,真正的下載也要負責執行。從傳送請求到接受檔案,這些工作,一旦你run了這個任務,就會開始執行。

Task_manager:工作管理員類,它主要就是像使用者管理器那樣動態監測其中成員的狀態,其中有3個集合,running中的任務、success的任務、error的任務。主要職能是根據實時

4 結語

從展示的可執行的程式的截圖,程式在VS2013中除錯沒有問題,也生成了release版本,介面是用coco2dx寫的,主要是考慮到可移植性,

熱門標籤