1. 程式人生 > >廣播路由演算法 :我是如何優雅著把悄悄話帶給其他人的

廣播路由演算法 :我是如何優雅著把悄悄話帶給其他人的

對於廣播,我相信在現實生活中我們時常都能接觸到,例如學校一言不合就響起了校歌,搞的全校的人都能夠聽到,想假裝沒聽到都不行。

假如我們把學校比作一個區域網的話,某臺主機發起了一個廣播,意味著區域網內的其他所有主機都會收到這個廣播,那發起廣播的主機是如何選擇路徑來給其他主機發送廣播分組的呢?考慮下面由幾個節點組成的網路:

假如節點 R1 要做一個廣播給 R2, R3, R4發廣播分組,顯然,一種很簡單的方法就是R1給 R2, R3, R4三個節點分別發一次廣播分組,這意味著R1一共要傳送三次同樣的廣播分組。

途中不同箭頭的顏色表示R1給不同的節點發廣播分組。

大家想一個問題:這種傳送方式你覺得合理嗎?

是的,這種傳送方式在實現上很簡單,源節點(R1)每次帶上目的節點的地址,然後傳送給它就行了。

不過這種方式方式在效率上是極低的,例如,R1傳送的這三個廣播分組都會經過同一段鏈路(R1-R2這段鏈路),而且R2要是再連線上n個節點的話,代表著這R1需要再發送n次廣播分組,這n個報文也會經過同一段鏈路。

解決方法

為了解決這個問題,我們或許可以這樣做:就是R1把廣播分組發給他的鄰居節點R2,然後R1就不管了,R2再把報文傳送給他的所有鄰居節點R3, R4(除了從其接收該分組的那個鄰居R1)。

顯然這種方式也是挺不錯的,R1只發送了一次廣播分組,而且R1-R2這段鏈路也不會出現同一個廣播分組重複經過的情況。嗯,這很nice。

廣播風暴

不過,這種給所有鄰居節點發送廣播分組的方式夠優雅嗎?

看下面的一個網路組成:

按照剛才的方法,R1會給R2傳送廣播分組,接著R2會給R3, R4傳送廣播分組。剛才我們說過,收到廣播分組的節點會給他的所有鄰居傳送報文(除了從其接受到該報文的那個鄰居)。

所以這個時候 R3會給R4傳送廣播分組文,而R4接收到R3的廣播分組之後,R4會給R2傳送廣播分組,R2收到R4的廣播分組之後 ,也會給R3再次傳送廣播分組.....

如果節點中形成了一個圈,那麼就會像上面那樣,節點之間不停著傳送廣播分組,這時網路上充斥著大量重複的廣播分組,這將會嚴重影響資源的利用。

我們也把這種情況稱之為廣播風暴

控制廣播風暴

因此,我們必須想出某種策略,來控制這種廣播風暴。

一種很簡單的方法,就是給這一份廣播分組做一個標記。例如,源節點(發起廣播的節點)可以將其地址以及廣播序號放入這個廣播分組中,然後傳送給他的所有鄰居節點,每個節點會維護它已經收到的、轉發的源地址和廣播分組的序號列表

當節點收到一個廣播分組時,會檢查這個廣播分組是否之前接收過(可以通過源地址、報文序號來檢查),如果接收過,那麼就把該廣播分組丟棄,否則,把該廣播分組接收,且向所有鄰居節點轉發。

例如對於下面由7個節點組成是網路

如果 節點 A 要做一個廣播,那麼 A就會給他的鄰居節點B,C發一份廣播分組,B,C也會給他的鄰居節點發送一個廣播分組。意味著B會給 C,D傳送廣播分組,而 C也會給 B,E,F傳送一份廣播分組:

當B收到C發給他的報文時,B檢測到已經有了該報文,所以B會丟棄C傳送給他的廣播分組,C也一樣會丟棄B傳送給他的廣播分組。圖中青色的箭頭代表該廣播分組會被丟棄。

從圖中不難看出,就算節點之間形成了圈,但也不會出現節點之間迴圈轉發的情況。

雖然該方法簡單 ,但確實有效著控制了廣播風暴,當然,這只是控制廣播風暴的方法之一,實際上還有其他方法,在此我就不說了。

生成樹廣播

雖然上面的那種方法有效著控制了廣播風暴,但也是存在著很多的冗餘廣播分組(那些被丟棄的廣播分組就是冗餘的廣播分組)。

如果可以,我想讓每個節點僅接收一次廣播分組,也不用 考慮丟棄廣播分組,所以理想的情況應該是這樣:

有沒有一種方法,可以讓廣播分組像上面這種情況來傳送呢?請大家看下面一個圖:

如果把節點當作一個的頂點,大家觀察下左邊的圖與右邊的圖有什麼聯絡。

右邊的圖不就是左邊圖的生成樹嗎?(學了這麼多年的生成樹,終於給用到了),如果我們給每一段鏈路加上相應的費用的話,那麼我們最理想的情況就是找到一顆最小生成樹

所以,我們最理想的情況就是讓廣播報文在最小生成樹的路徑中傳送,於是 ,我們現在的問題就是找出這些節點組成的網路中的最小生成樹。

那麼,如何構造一顆生成樹呢?下面提供一種基於中心某個中心的方法來建立一顆生成樹。注意,是生成樹,不是最小生成樹

該方法是這樣的:我們先選出一箇中心節點,然後其他節點向這個中心節點發送加入樹報文,加入樹報文經過的路徑,都會被嫁接到生成樹上。我舉個例子吧,好理解點。例如對於這個網路結構:

我們選擇 E為中心點,然後其他節點給E傳送加入樹報文:

1、F節點給E傳送加入樹報文,此時E-F鏈路成為初始的生成樹,如下圖(紅色路徑表示生成樹)

2、接著B給E傳送加入樹報文,假設B經過的路徑是B->D->E。此時路徑B-D-E也加入了生成樹。

注:D不用在不用在傳送加入樹報文了,因此他此時已經在生成樹裡了。

3、接著C給E傳送加入樹報文,C-E加入生成樹。

4、接著,A給E傳送報文,假設A選擇的路徑是A->C->E。不過當A的報文到達C之後,由於原本C-E就在生成樹裡面了,所以A的報文不用經過C-E,A-C就加入到生成樹了。

5、最後G通過D加入生成樹。

到此,生成樹構建完畢,此時生成樹如下:

然後在廣播的時候,就可以沿著這條路徑來轉發複製廣播報文了。

文章講到這裡,也大致結束。如果文中有哪裡講錯了,歡迎你指出一下。

更多文章目錄導航:https://github.com/iamshuaidi/writing