學習《UNIX網路程式設計卷一》筆記
P110解決網路程式設計可能會遇到的三種情況:
(1)當fork子程序時,必須捕獲SIGCHLD訊號;(理解:這裡的捕獲不是立即去捕獲,而是註冊捕獲訊號,隨時在子程序傳送訊號的時候了,就捕獲。為什麼要早註冊呢,是因為你不知道子程序什麼時候發。)
(2)當捕獲訊號時,必須處理被中斷的系統呼叫;
(3)SIGCHLD的訊號處理函式必須正確編寫,應使用waitpid函式以免留下僵死程序。
P120解決穿越套接字傳送二進位制結構的問題:
(1)把所有的數值作為文字串來傳遞,這樣就不會引起不同格式二級制數和大小端主機的問題;
(2)顯示定義所支援資料型別的二進位制格式(位數、大端或小端位元組序)。
P172Nagle演算法
在於減少廣域網上小分組的數目。該演算法指出,如果某個給定連線上有待確認資料,那麼原本應該作為使用者寫操作響應的在該連線上立即傳送相應小分組的行為就不會發生,知道現有資料被確認為止。
經常與ACK演算法聯用:ACK演算法使得TCP在接收到資料後不立即傳送ACK,而是等待一段時間(50~200ms),然後才傳送ACK。
有三種辦法修改不適合使用上述兩種演算法:
(1)使用writev,writev呼叫最終導致呼叫TCP輸出功能一次而不是兩次,其結果是產生一個TCP分節;
(2)把前4位元組的資料和後396資料複製到單個緩衝區,然後對該緩衝區呼叫一次write;
(3)設定TCP_NODELAY套接字選項,繼續呼叫write兩次。這是不可取的方法會損害網路。
P189UDP和TCP的區別
大多數TCP伺服器是一個併發伺服器,而大多數UDP伺服器是迭代伺服器。
udp的客戶服務程式是不可靠的。如果一個客戶資料包丟失,或者是客戶資料包到達了但是伺服器無法應答,客戶將永遠阻塞在recvfrom。防止這樣永久阻塞的方法是給客戶recvfrom設定一個超時。
P270可重入和不可重入的問題
不可重入函式會造成在不同執行緒間呼叫時,全域性變數的值發生改變;
而可重入函式呼叫malloc分配記憶體容易造成記憶體的洩露。
P286守護程序
daemon是在後臺執行且不與任何控制終端關聯的程序,常源於系統初始化指令碼啟動。
P316避免在套接字上使用標準I/O函式庫
當標準I/O流的便利性大過對緩衝帶來的bug擔憂時,在套接字上使用標準I/O流是可行的,但是這種情況也罕見。
P362非阻塞accept解決的問題
當採用select返回監聽套接字的可讀條件時,遇到一個繁忙的伺服器和客戶程式馬上傳送RST斷開連線時會出現問題,使伺服器程式阻塞於accept而無法處理其他已經就緒的套接字描述符。
解決的辦法是:(1)當使用select獲悉某個監聽套接字完成連線準備被accept時,把這個監聽套接字設定為非阻塞;
(2)在後續的accept呼叫中忽略以下錯誤,比如EWOULDBLOCK等。
P366和網路相關ioctl的請求
套接字請求,檔案操作,介面操作,ARP快取記憶體操作,路由表操作,流系統。
P425訊號會在程式執行過程中由核心隨時隨地提交,容易阻塞在recvfrom中,解決辦法是
用pselect函式阻塞解阻塞訊號,它設定訊號掩碼,測試描述符以及恢復訊號掩碼這三個操作在呼叫程序看來是一個原子操作;
使用sigsetjmp和siglongjmp同樣可以;
使用從訊號處理函式到主控函式的IPC,管道通訊的測試跳出for迴圈來防止。
P467UDP和TCP的區別,何時用UDP代替TCP
TCP是可靠的,而UDP是不可靠的;
事實上如果應用程式使用廣播或多播,就必須使用UDP;
UDP沒有連線的建立和拆除
對於實時音訊能夠通過插值彌補遺失資料,那麼丟失的分節也許不必要重傳,可以使用UDP;
如果兩端事先協定請求和應答的大小,那麼也許不需要視窗式流量控制,可以使用UDP;
對於海量資料傳輸不應該使用UDP。
如今良好的TCP實現能夠充分發揮網路頻寬容量,而且越來越多的應用程式設計願意在UDP中再造一個TCP。
P534程序與執行緒呼叫的網路程式設計區別
程序fork要把父程序的記憶體映像複製到子程序;
父子程序之間的通訊採用IPC模式;
執行緒為輕權程序,建立速度更快;
執行緒間共享全域性記憶體,易於共享,但需要考慮同步問題。
p674客戶/伺服器程式設計正規化
迭代伺服器,無程序;
併發伺服器,每個客戶請求fork一個子程序;
預先派生子程序,每個子程序無保護的呼叫accept;
預先派生子程序,使用檔案上鎖保護accept;
預先派生子程序,使用執行緒互斥鎖上鎖保護accept;
預先派生子程序,父程序向子程序傳遞套接字描述符;
併發伺服器,每個客戶請求建立一個執行緒;
預先建立執行緒伺服器,使用互斥鎖上鎖保護accept;
預先建立執行緒伺服器,由主執行緒呼叫accept。
p674客戶/伺服器程式設計正規化的對比
負載較輕時,選擇併發伺服器即可;
相比並發伺服器,預先建立子程序池或者執行緒池更快;
讓所有子程序或執行緒自行呼叫accept比單獨讓父程序或主執行緒呼叫accept然後傳遞描述符更快;
讓所有子程序或執行緒阻塞在同一個accept比阻塞在同一個select更可取;
使用執行緒比程序更快,不過也取決於具體的作業系統。