前言
繼續補上我的部落格,這幾天專注把【unix網路程式設計】的內容總結。
1.單播與廣播的比較
單播 過程:
中間主機的乙太網介面看到該幀,並將它的目的乙太網與自己的乙太網位址進行比較。由於二者不相等,介面便忽略該幀。因此,單播幀不會對這台主機造成任何額外開銷,因為忽略它們的是介面而不是主機。
右邊主機的乙太網介面也看到該幀。並將它的目的乙太網與自己的乙太網位址進行比較。發現二者相等,介面便讀入該幀。
廣播過程:
由於是廣播型別的資料報,右側的兩台主機都將資料報傳遞到ip層。但是由於中間的主機沒有任何應用程序繫結相應的udp埠,於是主機的udp**丟棄這個已收到的資料報。
20.4中的例子
圖20-5中使用廣播技術的回射客戶程式,使用廣播位址把輸入的字串傳送給子網裡所有的主機,設定了broadcast選項。
setsockopt(sockfd, sol_socket, so_broadcast, &on, sizeof(on));
不過在我自己的主機上執行時發現,不設定此項同樣可以執行,這一點應該和各個核心實現有關,為了有更加優良的移植性,最好還是加上這一段**。
2.競爭狀態
什麼是競爭狀態:
此處所說的競爭狀態主要是針對unix系統中的訊號來說的,在系統執行的過程中,如果某個函式呼叫會阻塞,並且打算使用unix訊號(比如sigalrm定時)來中斷這個呼叫,那麼就有可能遇上別的函式呼叫的時候,這個訊號產生了,沒能成功的在阻塞函式呼叫時候中斷。這就是競爭狀態。
在unp書中,這裡是希望使用sigalrm訊號來中斷阻塞的recvfrom呼叫,但是由於未考慮如果sigalrm訊號產生時未能中斷recvfrom函式的情況,因此可能會一直阻塞在recvfrom函式中。
解決方法:
1. 使用片pselect阻塞和解阻塞訊號
做法是:
a.呼叫
sigprocmask(sig_block, &sigset_alrm, null);
b.調研pselect函式,該函式在阻塞階段將儲存之前的訊號掩碼,並設定成現在的掩碼
pselect(sockfd+1, &rset, null, null, null, &segset_empty);
c. 在pseelect阻塞時,訊號是可以遞交的,但單pselect返回了之後,又會恢復到之前阻塞訊號的掩碼,因此,此時訊號是不可以中斷函式呼叫的。
2.使用sigsetjmp和siglongjmp
siglongjmp可以從乙個函式轉跳到另乙個函式中,稱為「非區域性轉跳」
a.先呼叫sigsetjmp建立轉跳緩衝區然後返回0
if( sigsetjmp(jmpbuf, 1) !=0)
break;
在訊號來臨時,在中斷函式裡呼叫siglongjmp
siglongjmp(sigbuf, 1);
這樣會導致上面的sigsetjmp函式返回1.然後呼叫break;
3.使用ipc
(inter-process communication,程序間通訊 方式
a.建立乙個管道
int pipefd[2];
pipe(pipefd);
b.使用select測試套接字和管道fd_set(sockfd, &rset);
fd_set(pipefd[0], &rset);
select(maxfdp1, &rset, null, null, null);
c.在中斷函式中網管道中寫入乙個字,因此pipefd將會變成可讀,避免了競爭。
總結
競爭問題的產生還是由於使用了unix訊號,想讓訊號中斷在理想的地方時很難的,因此只能使用通知主程序的方式。
所以ipc方法和select阻塞,我覺得是最方便且合適的方法。
TCP IP網路程式設計 多播與廣播
前言 想想這麼一種情況,網路電台可能需要同時向成千上萬的使用者傳輸相同的資料,如果用我們以前講過的傳輸形式,每個使用者都傳輸一次,這樣肯定是不合理的。因此,就引入了多播技術來解決這個問題,它可以同時向大量使用者傳送相同資料。其基本原理是這樣的 有個多播組,只要加入這個組裡的所有客服端,服務端傳送的資...
廣播與多播
廣播和多播僅用於udp。乙個主機要向網上的所有主機傳送幀,這就是廣播 每個乙太網幀僅發住單個目的主機,目的位址指明單個接收介面,因而稱為單播。多播介於單播與廣播之間 幀僅傳送給屬於多播組的多個主機 ip多播提供兩類服務 1 向多個目的位址傳送資料。有許多向多個接收者傳送資訊的應用 例如互動式會議系統...
socket程式設計(3)廣播 多播
廣播 廣播是指在乙個區域網中向所有的網上節點傳送資訊。這是udp連線的一種 廣播有乙個廣播組,即只有乙個廣播組內的節點才能收到發往這個廣播組的資訊。什麼決定了乙個廣播組呢,就是埠號,區域網內乙個節點,如果設定了廣播屬性並監聽了埠號a後,那麼他就加入了a組廣播,這個區域網內所有發往廣播埠a的資訊他都收...