20145337 《信息安全系統設計基礎》第十三週學習總結
教材學習內容總結
網絡編程
客戶端-服務器編程模型
- 一個服務器進程 -> 管理某種資源 -> 經過操做這種資源來爲它的客戶端提供某種服務
- 一個或多個客戶端進程
基本操做:事務
- 當一個客戶端須要服務時,向服務器發送一個請求,發起一個事務。
- 服務器收到請求後,解釋它,並以適當的方式操做它的資源。
- 服務器給客戶端發送一個相應,並等待下一個請求。
- 客戶端收到響應並處理它。
- 客戶端和服務器都是進程,不是機器或者主機
- 一臺主機可同時運行許多不一樣客戶端服務器,且同一個客戶端服務器的事務可在同一臺或不一樣臺主機運行

網絡
- 對主機而言,網絡是一種I/O設備:從網絡上接收到的數據從適配器通過I/O和存儲器總線拷貝到存儲器,典型地是經過DMA(直接存儲器存取方式)傳送。
- 物理上,網絡是一個按照地理遠近組成的層次系統:最低層是LAN(局域網),最流行的局域網技術是以太網。
- 以太網段
- 包括一些電纜和集線器。每根電纜都有相同的最大位帶寬,集線器不加分辯地將一個端口上收到的每一個位複製到其餘全部的端口上,所以每臺主機都能看到每一個位。
- 每一個以太網適配器都有一個全球惟一的48位地址,存儲在適配器的非易失性存儲器上。
- 一臺主機能夠發送一段位:幀,到這個網段內其它任何主機。每一個幀包括一些固定數量的頭部位(標識此幀的源和目的地址及幀長)和數據位(有效載荷)。每一個主機都能看到這個幀,可是隻有目的主機能讀取。
- 使用電纜和網橋,多個以太網段能夠鏈接成較大的局域網,稱爲橋接以太網。這些電纜的帶寬能夠是不一樣的。
- 多個不兼容的局域網能夠經過叫作路由器的特殊計算機鏈接起來,組成一個internet互聯網絡。
- 互聯網重要特性:由採用不一樣技術,互不兼容的局域網和廣域網組成,並能使其相互通訊。其中不一樣網絡相互通訊的解決辦法是一層運行在每臺主機和路由器上的協議軟件,消除不一樣網絡的差別。
- 協議提供的兩種基本能力
- 命名機制:惟一的標示一臺主機
- 傳送機制:定義一種把數據位捆紮成不連續的片的同一方式
互聯網絡思想的精髓,封裝是關鍵html
全球IP因特網
- TCP/IP協議族
- 混合使用套接字接口函數和UnixI/O函數進行通訊
- TCP提供進程間可靠的、全雙工鏈接。
- 特性:
- 主機集合被映射爲一組32位的IP地址
- 這組IP地址被映射爲一組稱爲因特網域名的標識符
- 因特網主機上的進程可以經過鏈接和任何其餘主機上的進程
- 檢索並打印一個DNS主機條目:
#include "csapp.h"
int main(int argc, char **argv)
{
char **pp;
struct in_addr addr;
struct hostent *hostp;
if (argc != 2) {
fprintf(stderr, "usage: %s <domain name or dotted-decimal>\n",
argv[0]);
exit(0);
}
if (inet_aton(argv[1], &addr) != 0)
hostp = Gethostbyaddr((const char *)&addr, sizeof(addr), AF_INET);
else
hostp = Gethostbyname(argv[1]);
printf("official hostname: %s\n", hostp->h_name);
for (pp = hostp->h_aliases; *pp != NULL; pp++)
printf("alias: %s\n", *pp);
for (pp = hostp->h_addr_list; *pp != NULL; pp++) {
addr.s_addr = ((struct in_addr *)*pp)->s_addr;
printf("address: %s\n", inet_ntoa(addr));
}
exit(0);
}
套接字接口

Web服務器
- 協議
- Web 客戶端和服務器之間的交互用的是一個基於文本的應用級協議,叫作 HTTP (Hypertext Transfer Protocol,超文本傳輸協議). HTTP 是一個簡單的協議。一個 Web 客戶端(即瀏覽器) 打開一個到服務器的因特網鏈接,而且請求某些內容。服務器響應所請求的內容,而後關閉鏈接。瀏覽器讀取這些內容,並把它顯示在屏幕上。
- 內容
- Web內容能夠用一種叫作 HTML(Hypertext Markup Language,超文本標記語言)的語言來編寫。一個 HTML 程序(頁)包含指令(標記),它們告訴瀏覽器如何顯示這頁中的各類文本和圖形對象。
- Web 服務器以兩種不一樣的方式向客戶端提供內容:
取一個磁盤文件,並將它的內容返回給客戶端。磁盤文件稱爲靜態內容 (static content), 而返回文件給客戶端的過程稱爲服務靜態內容 (serving static content)。 運行一個可執行文件,並將它的輸出返回給客戶端。運行時可執行文件產生的輸出稱爲態內容 (dynamic content),而運行程序並返回它的輸出到客戶端的過程稱爲服務動態內容 (serving dynamic content)。程序員
併發編程
-應用級併發
- 訪問慢速I/O設備
- 與人交互
- 經過推遲工做以下降延遲
- 服務多個網絡客戶端
- 在多核機器上進行並行計算
- 進程
- I/O多路複用
線程web
基於進程的併發編程
- 構造併發服務器的天然方法就是,在父進程中接受客戶端鏈接請求,而後建立一個新的子進程來爲每一個新客戶端提供服務。
- 由於父子進程中的已鏈接描述符都指向同一個文件表表項,因此父進程關閉它的已鏈接描述符的拷貝是相當重要的,並且由此引發的存儲器泄露將最終消耗盡可用的存儲器,使系統崩潰。
- 優勢:
- 進程有獨立的地址空間
- 缺點:
進程控制和IPC開銷高,速度慢編程
基於I/O多路複用的併發編程
- echo服務器必須響應兩個相互獨立的I/O時間:
- 網絡客戶端發起鏈接請求
- 用戶在鍵盤上鍵入命令行
- I/O多路複用技術的基本思路:使用select函數,要求內核掛起進程,只有在一個或多個I/O事件發生後,纔將控制返回給應用程序。
- 將描述符集合當作是n位位向量:b(n-1),……b1,b0 ,每一個位bk對應於描述符k,當且僅當bk=1,描述符k才代表是描述符集合的一個元素。能夠作如下三件事:
- 分配它們;
- 將一個此種類型的變量賦值給另外一個變量;
- 用FDZERO、FDSET、FDCLR和FDISSET宏指令來修改和檢查它們。
- echo函數:未來自科幻段的每一行回送回去,直到客戶端關閉這個連接。
- 狀態機就是一組狀態、輸入事件和轉移,轉移就是將狀態和輸入時間映射到狀態,自循環是同一輸入和輸出狀態之間的轉移。
- 事件驅動器的設計優勢:
- 比基於進程的設計給了程序員更多的對程序行爲的控制
- 運行在單一進程上下文中,所以,每一個邏輯流都能訪問該進程的所有地址空間,使得流之間共享數據變得很容易。
- 不須要進程上下文切換來調度新的流。
- 缺點:
- 編碼複雜
- 不能充分利用多核處理器
粒度:每一個邏輯流每一個時間片執行的指令數量。併發粒度就是讀一個完整的文本行所須要的指令數量。瀏覽器
基於線程的併發編程
- 線程:運行在進程上下文中的邏輯流。
- 線程有本身的線程上下文,包括一個惟一的整數線程ID、棧、棧指針、程序計數器、通用目的寄存器和條件碼。全部運行在一個進程裏的線程共享該進程的整個虛擬地址空間。
- Posix 線程
- Posix 線程 (Pthreads) 是在 C 程序中處理線程的一個標準接口。Pthreads 定義了大約 60 個函數,容許程序建立、殺死和回收線程,與對等線程安全地共享數據,還能夠通知對等線程系統狀態的變化。
- 線程的代碼和本地數據被封裝在一個線程例程(thread routine) 中。若是想傳遞多個參數給錢程例程,那麼你應該將參數放 到一個結構中,並傳遞一個指向該結構的指針。想要線程例程返回多個參數,你能夠返回一個指向一個結構的指針。
- 建立線程
- pthread_create 函數建立一個新的線程,並帶着一個輸入變量arg,在新線程的上下文中運行線程例程f。能用attr參數來改變新建立線程的默認屬性。
- 當 pthreadcreate 返回時,參數 tid包含新建立線程的ID。新線程能夠經過調用 pthreadself 函數來得到它本身的線程 ID.
- 終止線程
- 當頂層的線程例程返回時,線程會隱式地終止。 經過調用 pthreadexit 函數,線程會顯式地終止。若是主線程調用 pthreadexit , 它會等待全部其餘對等線程終止,而後再終止主線程和整個進程,返回值爲 thread_return。
- 回收已終止線程的資源
- 線程經過調用 pthread_join 函數等待其餘線程終止。
- pthreadjoin 函數會阻塞,直到線程 tid 終止,將線程例程返回的 (void*) 指針賦值爲 threadreturn 指向的位置,而後回收己終止線程佔用的全部存儲器資源。
- pthread join 函數只能等待一個指定的線程終止。
- 分離線程
- 在任何一個時間點上,線程是可結合的 (joinable) 或者是分離的 (detached)。一個可結合的線程可以被其餘線程收回其資源和殺死。在被其餘線程回收以前,它的存儲器資源(例如棧)是沒有被釋放的。相反,一個分離的線程是不能被其餘線程回收或殺死的。它的存儲器資源在它終止時由系統自動釋放。
- 默認狀況下,線程被建立成可結合的。爲了不存儲器泄漏,每一個可結合線程都應該要麼被其餘線程顯式地收回,要麼經過調用 pthread_detach 函數被分離。
- pthreaddetach 函數分離可結合線程 tid. 線程可以經過以 pthreadself()爲參數的 pthread_detach 調用來分離它們本身。
- 初始化線程
- pthread_once 函數容許你初始化與線程例程相關的狀態。
- 一個基於線程的併發服務器
調用 pthread_ create 時,如何將已鏈接描述符傳遞給對等線程。最明顯的方法就是傳遞一個指向這個描述符的指針。 對等線程間接引用這個指針,並將它賦值給一個局部變量。安全
進度圖
- 進度圖將指令執行模式化爲從一種狀態到另外一種狀態的轉換。轉換被表示爲一條從一點到相鄰點的有向邊。合法的轉換是向右或者向上。
- 臨界區:對於線程i,操做共享變量cnt內容的指令構成了一個臨界區。
- 互斥的訪問:確保每一個線程在執行它的臨界區中的指令時,擁有對共享變量的互斥的訪問。
- 安全軌跡線:繞開不安全區的軌跡線
- 不安全軌跡線:接觸到任何不安全區的軌跡線就叫作不安全軌跡線
任何安全軌跡線都能正確的更新共享計數器。服務器
信號量實現互斥
- 生產者-消費問題
- 讀者-寫者問題
代碼調試中的問題和解決過程
- condvar
消費者等待生產者產產出產品後打印
網絡
- count
不加鎖的建立兩個線程共享同一變量都實現加一操做
併發
- countwithmutex
引入互斥鎖
app
- cp_t
用法: ./cp_t [源文件名][目的文件名][建立線程數]

- createthread
打印進程和線程ID

semphore

- share
得到線程的終止狀態

threadexit

hello_multi

hello_multi1

hello_single

incprint

- twordcount1
統計文件1和文件2兩個文件的總字數

twordcount2

- twordcount3
分別對文件一、2兩個文件進行字數統計,並把兩個文件的字數加起來統計總字數

twordcount4

分別運行代碼根據鎖的狀況分別統計字數,再把兩個文件的字數加起來統計總字數
本週代碼託管截圖

其餘(感悟、思考等,可選)
這周主要學習了網絡編程及併發編程的相關知識,自己看着比較複雜,但結合JAVA WEB和操做系統這兩門課,就容易理解多了。在JAVA WEB中實現客戶端-服務器模型 寥寥幾十行代碼,只是學到了皮毛,仔細看十一章,才明白其中原理。期末將近,最後幾周但願能補上一些,花更多的時間理解把知識掌握紮實。
學習進度條
目標 |
5000行 |
30篇 |
400小時 |
|
第十三週 |
200/200 |
2/2 |
20/20 |
學習網絡編程及併發編程相關知識 |
參考資料