# 網路 (Networking) ## OSI 七層 > https://zh.wikipedia.org/wiki/OSI%E6%A8%A1%E5%9E%8B ### 應用層(Application Layer) * 提供為應用軟體而設的介面,以設定與另一應用軟體之間的通訊。 * 例如: HTTP,HTTPS,FTP,TELNET,SSH,SMTP,POP3 ### 表現層(Presentation Layer) * 把資料轉換為能與接收者的系統格式相容並適合傳輸的格式。 * ==已棄用== ### 會議層(Session Layer) * 負責在資料傳輸中設定和維護電腦網路中兩台電腦之間的通訊連接。 * ==已棄用== ### 傳輸層(Transport Layer) * 把傳輸表頭(TH)加至資料以形成資料包(Datagram)。傳輸表頭包含了所使用的協定等傳送資訊。 * 例如:傳輸控制協定[TCP](https://zh.wikipedia.org/wiki/%E4%BC%A0%E8%BE%93%E6%8E%A7%E5%88%B6%E5%8D%8F%E8%AE%AE "傳輸控制協定")、UDP、DCCP、SCTP、RSVP、PPTP、[TLS/SSL](https://zh.wikipedia.org/wiki/%E5%AE%89%E5%85%A8%E5%A5%97%E6%8E%A5%E5%B1%82) ### 網路層(Network Layer) * 決定資料的路徑選擇和轉寄,將網路表頭(NH)加至資料包,以形成封包。網路表頭包含了網路資料。 * 例如:網際網路協定IP(v4·v6、ICMP(v6)、IGMP、IS-IS、IPsec、BGP、RIP、OSPF、RARP ### 資料連結層(Data Link Layer) * 負責網路尋址、錯誤偵測和改錯。當表頭和表尾被加至資料包時,會形成影格。資料鏈表頭(DLH)是包含了實體位址和錯誤偵測及改錯的方法。資料鏈表尾(DLT)是一串指示資料包末端的字串。例如乙太網、無線區域網路(Wi-Fi)和通用分組無線服務(GPRS)等。 * 分為兩個子層:邏輯鏈路控制(logic link control,LLC)子層和介質存取控制(media access control,MAC)子層。 * Wi-Fi(IEEE 802.11) ARP WiMAX(IEEE 802.16) ATM DTM ### 實體層(Physical Layer) * 在局部區域網路上傳送資料框(frame),它負責管理電腦通訊裝置和網路媒體之間的互通。 * 包括了針腳、電壓、線纜規範、集線器、中繼器、網卡、主機介面卡等 ## HTTP Protocols [![](https://upload.wikimedia.org/wikipedia/commons/thumb/8/83/Internet1.svg/220px-Internet1.svg.png)](https://zh.wikipedia.org/wiki/File:Internet1.svg) HTTP是一個用戶端終端(用戶)和伺服器端(網站)請求和應答的標準([TCP](https://zh.wikipedia.org/wiki/TCP "TCP"))。通過使用[網頁瀏覽器](https://zh.wikipedia.org/wiki/%E7%B6%B2%E9%A0%81%E7%80%8F%E8%A6%BD%E5%99%A8 "網頁瀏覽器")、[網路爬蟲](https://zh.wikipedia.org/wiki/%E7%BD%91%E7%BB%9C%E7%88%AC%E8%99%AB "網路爬蟲")或者其它的工具,用戶端發起一個HTTP請求到伺服器上指定埠port為80。 我們稱用戶端為**用戶代理程式(user agent**,應答的伺服器上儲存著一些資源,比如HTML檔案和圖像,稱應答伺服器為**源伺服器(origin server)**。在用戶代理和源伺服器中間可能存在多個「中間層」,比如[代理伺服器](https://zh.wikipedia.org/wiki/%E4%BB%A3%E7%90%86%E4%BC%BA%E6%9C%8D%E5%99%A8 "代理伺服器")、[閘道器](https://zh.wikipedia.org/wiki/%E7%BD%91%E5%85%B3 "閘道器")或者[隧道](https://zh.wikipedia.org/wiki/%E9%9A%A7%E9%81%93 "隧道")(tunnel)。 通常,由HTTP用戶端發起一個請求,建立一個到伺服器指定埠(預設是80埠)的**TCP連線**。HTTP伺服器則在那個埠監聽用戶端的請求。一旦收到請求,伺服器會向用戶端返回一個狀態,比如"HTTP/1.1 200 OK",以及返回的內容,如請求的檔案、錯誤訊息、或者其它資訊。 有關HTTP狀態碼,如 * 100 Continue * 200 OK * 201 Created * 202 Accepted * 403 Forbidden * 404 Not Found Ref: https://zh.wikipedia.org/wiki/HTTP%E7%8A%B6%E6%80%81%E7%A0%81 ## HTTP版本 ### HTTP 0.9 已過時。只接受GET一種請求方法,沒有在通訊中指定版本號,且不支援請求頭。由於該版本不支援POST方法,因此用戶端無法向伺服器傳遞太多資訊。 ### HTTP 1.0 這是第一個在通訊中指定版本號的HTTP協定版本,至今仍被廣泛採用,特別是在[代理伺服器](https://zh.wikipedia.org/wiki/%E4%BB%A3%E7%90%86%E6%9C%8D%E5%8A%A1%E5%99%A8 "代理伺服器")中。 ### HTTP 1.1 **持久連線**被預設採用,並能很好地配合代理伺服器工作。還支援以[管道方式](https://zh.wikipedia.org/wiki/HTTP%E7%AE%A1%E7%BA%BF%E5%8C%96 "HTTP管線化")在同時傳送多個請求,以便降低線路負載,提高傳輸速度。 HTTP 1.1相較於HTTP 1.0協定的區別主要體現在: - 快取處理 - 頻寬最佳化及網路連線的使用 - 錯誤通知的管理 - 訊息在網路中的傳送 - 網際網路位址的維護 - 安全性及完整性 ### HTTP 2 [HTTP/2](https://zh.wikipedia.org/wiki/HTTP/2 "HTTP/2") 是目前主要版本,於2015年5月作為網際網路標準正式發布 ### 用戶端請求 ``` GET / HTTP/1.1 Host: www.google.com ``` ### 伺服器應答 ``` HTTP/1.1 200 OK Content-Length: 3059 Server: GWS/2.0 Date: Sat, 11 Jan 2003 02:44:04 GMT Content-Type: text/html Cache-control: private Set-Cookie: PREF=ID=73d4aef52e57bae9:TM=1042253044:LM=1042253044:S=SMCc_HRPCQiqy X9j; expires=Sun, 17-Jan-2038 19:14:07 GMT; path=/; domain=.google.com Connection: keep-alive ``` ## 持續連線 (HTTP Keep Alive) > Ref : [HTTP持久連線](https://zh.wikipedia.org/wiki/HTTP%E6%8C%81%E4%B9%85%E8%BF%9E%E6%8E%A5 "HTTP持久連線") [![](https://upload.wikimedia.org/wikipedia/commons/thumb/d/d5/HTTP_persistent_connection.svg/langzh-350px-HTTP_persistent_connection.svg.png)](https://zh.wikipedia.org/w/index.php?title=File:HTTP_persistent_connection.svg&lang=zh) 使用多個連線和使用持久連結的對比 * 在HTTP 0.9和1.0中,[TCP連線](https://zh.wikipedia.org/wiki/%E4%BC%A0%E8%BE%93%E6%8E%A7%E5%88%B6%E5%8D%8F%E8%AE%AE "傳輸控制協定")在每一次請求/回應對之後關閉。 * 在HTTP 1.1中,引入了保持連線的機制,一個連接可以重複在多個請求/回應使用。持續連線的方式可以大大減少[等待時間](https://zh.wikipedia.org/wiki/%E5%BB%B6%E8%BF%9F_(%E5%B7%A5%E7%A8%8B%E5%AD%A6) "延遲 (工程學)"),因為在發出第一個請求後,雙方不需要重新執行[TCP交握程式](https://zh.wikipedia.org/wiki/%E6%8F%A1%E6%89%8B_(%E6%8A%80%E6%9C%AF) "握手 (技術)")。 * HTTP 1.1還使改進了HTTP 1.0的頻寬。 例如,HTTP 1.1引入了[分塊傳輸編碼](https://zh.wikipedia.org/wiki/%E5%88%86%E5%9D%97%E4%BC%A0%E8%BE%93%E7%BC%96%E7%A0%81 "分塊傳輸編碼"),以允許傳遞內容可以在持續連線上被串流傳輸而不必使用到[緩衝器](https://zh.wikipedia.org/wiki/%E7%B7%A9%E8%A1%9D%E5%99%A8 "緩衝器")。HTTP管道允許客戶端在收到每個回應之前發送多個請求,進一步減少[用戶感受到的](https://zh.wikipedia.org/wiki/%E4%BD%BF%E7%94%A8%E8%80%85%E7%B6%93%E9%A9%97 "使用者經驗")滯後時間。 ### 優勢 - 較少的[CPU](https://zh.wikipedia.org/wiki/CPU "CPU")和記憶體的使用(由於同時開啟的連線的減少了) - 允許請求和應答的[HTTP管線化](https://zh.wikipedia.org/wiki/HTTP%E7%AE%A1%E7%B7%9A%E5%8C%96 "HTTP管線化") - 降低[擁塞控制](https://zh.wikipedia.org/wiki/%E6%8B%A5%E5%A1%9E%E6%8E%A7%E5%88%B6 "擁塞控制") ([TCP連線](https://zh.wikipedia.org/wiki/%E4%BC%A0%E8%BE%93%E6%8E%A7%E5%88%B6%E5%8D%8F%E8%AE%AE "傳輸控制協定")減少了) - 減少了後續請求的[延遲](https://zh.wikipedia.org/wiki/%E5%BB%B6%E9%81%B2_(%E9%9B%BB%E8%85%A6) "延遲 (電腦)")(無需再進行[握手](https://zh.wikipedia.org/wiki/%E6%8F%A1%E6%89%8B_(%E6%8A%80%E6%9C%AF) "握手 (技術)")) - 報告錯誤無需關閉TCP連線 ### 劣勢 對於現在的廣泛普及的寬頻連線來說,Keep-Alive也許並不像以前一樣有用。web伺服器會保持連線若干秒(Apache中預設15秒),這與提高的效能相比也許會影響效能。 對於單個檔案被不斷請求的服務(例如圖片存放網站),Keep-Alive可能會極大的影響效能,因為它在檔案被請求之後還保持了不必要的連線很長時間。 ## HTTP、Socket、TCP/IP的關係? > Ref : https://twgame.wordpress.com/2015/02/03/tcpiphttpsocketudp/ * 傳輸層的TCP是基於網絡層的IP協議的,而應用層的HTTP協議又是基於傳輸層的TCP協議的,三者從本質上來說是完全不同。 * Socket則是對TCP/IP協議的封裝和應用(程序員層面上)。 * Socket的出現只是使得碼農更方便地使用TCP/IP協議棧而已,是對TCP/IP協議的抽象,而形成了一些最基本的函數接口,比如create、listen、connect、accept、send、read和write等等。 ## TCP 三方交握(Three Way Handshake) ![](http://linux.vbird.org/linux_server/0110network_basic//3_hand_shak.png) 1. 第一次握手:客戶端發送syn包(syn=j)到服務器,並進入SYN_SEND狀態,等待服務器確認; 2. 第二次握手:服務器收到syn包,必須確認客戶的SYN(ack=j+1),同時自己也發送一個SYN包(syn=k),即SYN+ACK包,此時服務器進入SYN_RECV狀態; 3. 第三次握手:客戶端收到服務器的SYN+ACK包,向服務器發送確認包ACK(ack=k+1),此包發送完畢,客戶端和服務器進入ESTABLISHED狀態,完成三次握手。 握手過程中傳送的包裏不包含數據,三次握手完畢後,客戶端與服務器才正式開始傳送數據。理想狀態下,TCP連接一旦建立,在通信雙方中的任何一方主動關閉連接之前,TCP 連接都將被一直保持下去。 ## HTTP Session 與Cookie的差別 > 好文推推 https://blog.hellojcc.tw/2016/01/12/introduce-session-and-cookie/ ### Cookie 最常見到的 Cookie 應用是在**表單填寫**:假設現在頁面上的資料填到一半,不小心把網頁關掉,這時再重新打開發現先前填的內容還在的話,靠的就是 cookie。實作原理很簡單,client 端的程式在一旦填寫的資料有變動時,就把該資訊寫入 cookie。 Cookie 由瀏覽器處理,具有兩個特性: - Domain specific:只針對原本的 domain 起作用。舉例,在 `*.example.com` 存入的 cookie,不會出現在 `*.not-example.com`。 - 到了所設定的生命期限之後會失效。 Cookie 的另一個特性是:==在向該 domain 的 server 發送請求時,也會被一併帶進去該請求中==。因此,記得不要讓 cookie 的內容太多,會增加傳輸量的負擔。另外透過這個特性,可以做到驗證客戶端的功能。 設想你某次登陸過一個網站,下次登錄的時候不想再次輸入賬號了,怎麼辦?這個信息可以寫到**Cookie**裡面,訪問網站的時候,網站頁面的腳本可以讀取這個信息,就自動幫你把用戶名給填了,能夠方便一下用戶。 :heart_eyes:這也是Cookie名稱的由來,給用戶的一點甜頭。 --- ### Session Session 負責==紀錄在 web server 上的使用者訊息==。Session 機制會在一個用戶完成身分認證後,存下所需的用戶資料,接著產生一組對應的 `ID`,存入 cookie 後傳回用戶端。 Session就比如購物車,當你點擊下單按鈕時,由於HTTP協議無狀態,所以並不知道是哪個用戶操作的,所以服務端要為特定的用戶創建了特定的Session,用用於標識這個用戶,並且跟踪用戶,這樣才知道購物車裡面有幾本書。 這個 ID 要是獨特的,所以會使用 [uuid](https://www.wikiwand.com/zh/%E9%80%9A%E7%94%A8%E5%94%AF%E4%B8%80%E8%AF%86%E5%88%AB%E7%A0%81) 的機制,重複的機率非常非常低。 因此當下次用戶端發送請求時,如果帶有該 `ID` 資訊,web server 就會認為該請求是來自該名使用者,達到驗證用戶的目的。這個時候防偽的機制就相當重要,如果伺服器端的實作有問題,再加上用戶端竄改 cookie,就有可能被偽造身分。 --- ### **Server Side如何識別特定的客戶**? 每次HTTP請求的時候,客戶端都會發送相應的Cookie信息到服務端。實際上大多數的應用都是用Cookie來實現Session跟踪的,第一次創建Session的時候,服務端會在HTTP協議中告訴客戶端==需要在Cookie裡面記錄一個Session ID,以後每次請求把這個Session ID發送到服務器,我就知道你是誰了==。 有人問,如果客戶端的瀏覽器禁用了Cookie怎麼辦?一般這種情況下,會使用一種叫做URL重寫的技術來進行會話跟踪,即每次HTTP交互,URL後面都會被附加上一個諸如sid=xxxxx這樣的參數,服務端據此來識別用戶。 ### 兩者差別 1. session保存在**伺服器**,用戶端不知道其中的資訊;cookie保存在**用戶端**,伺服器能夠知道其中的資訊。 2. Session是在服務端保存的一個數據結構,用來跟踪用戶的狀態,這個數據可以保存在集群、數據庫、文件中;Cookie是客戶端保存用戶信息的一種機制,用來記錄用戶的一些信息, 3. session不能區分路徑,同一個用戶在訪問一個網站期間,所有的session在任何一個地方都可以訪問到。而cookie中如果設置了路徑參數,那麼同一個網站中不同路徑下的cookie互相是訪問不到的。 ## 使用MVC架構的好處? > https://zh.wikipedia.org/wiki/MVC > ![](https://upload.wikimedia.org/wikipedia/commons/thumb/a/a0/MVC-Process.svg/400px-MVC-Process.svg.png =300x300) **MVC模式**(Model–view–controller)是[軟體工程](https://zh.wikipedia.org/wiki/%E8%BD%AF%E4%BB%B6%E5%B7%A5%E7%A8%8B "軟體工程")中的一種[軟體架構](https://zh.wikipedia.org/wiki/%E8%BD%AF%E4%BB%B6%E6%9E%B6%E6%9E%84 "軟體架構")模式,把軟體系統分為三個基本部分: 1. 模型(Model): 作為不同層面間的組織作用,用於控制應用程式的流程,它處理事件並作出回應。「事件」包括用戶的行為和資料 Model 上的改變 2. 視圖(View): 介面設計人員進行圖形介面設計 3. 控制器(Controller): 用於封裝與應用程式的業務邏輯相關的資料以及對資料的處理方法,程式設計師編寫程式應有的功能(實現**演算法**等等)、資料庫專家進行**資料管理和資料庫設計**(可以實現具體的功能)。 ### 優點 * MVC模式的目的是實現一種動態的程式設計,使後續對程式的修改和擴充功能簡化,並且使程式某一部分的重複利用成為可能。通過對複雜度的簡化,使程式結構更加直覺。 * 軟體系統通過對自身基本部分分離的同時也賦予了各個基本部分應有的功能,專業人員可以通過自身的專長分組 在最初的[JSP](https://zh.wikipedia.org/wiki/JSP "JSP")網頁中,像[資料庫](https://zh.wikipedia.org/wiki/%E6%95%B0%E6%8D%AE%E5%BA%93 "資料庫")查詢語句(SQL query)這樣的資料層代碼和像[HTML](https://zh.wikipedia.org/wiki/HTML "HTML")這樣的表示層代碼是混在一起。雖然有著經驗比較豐富的開發者會將資料從表示層分離開來,但這樣的良好設計通常並不是很容易做到的,實現它需要精心地計劃和不斷的嘗試。MVC可以從根本上強制性地將它們分開。儘管構造MVC應用程式需要一些額外的工作,但是它帶給我們的好處是毋庸置疑的。 首先,多個 View 能共享一個 Model 。如今,同一個Web應用程式會提供多種使用者介面,例如用戶希望既能夠通過瀏覽器來收發[電子郵件](https://zh.wikipedia.org/wiki/%E7%94%B5%E5%AD%90%E9%82%AE%E4%BB%B6 "電子郵件"),還希望通過手機來存取[電子信箱](https://zh.wikipedia.org/wiki/%E7%94%B5%E5%AD%90%E9%82%AE%E7%AE%B1 "電子信箱"),這就要求Web網站同時能提供[Internet](https://zh.wikipedia.org/wiki/Internet "Internet")介面和[WAP](https://zh.wikipedia.org/wiki/WAP "WAP")介面。在MVC設計模式中, Model 回應用戶請求並返迴響應資料,View 負責格式化資料並把它們呈現給用戶,業務邏輯和表示層分離,同一個 Model 可以被不同的 View 重用,所以大大提高了代碼的可重用性。 其次,Controller 是自包含(self-contained)指高獨立內聚的物件,與 Model 和 View 保持相對獨立,所以可以方便的改變應用程式的資料層和業務規則。例如,把資料庫從[MySQL](https://zh.wikipedia.org/wiki/MySQL "MySQL")移植到[Oracle](https://zh.wikipedia.org/wiki/Oracle "Oracle"),或者把[RDBMS](https://zh.wikipedia.org/wiki/RDBMS "RDBMS")資料來源改變成[LDAP](https://zh.wikipedia.org/wiki/LDAP "LDAP")資料來源,只需改變 Model 即可。一旦正確地實現了控制器,不管資料來自資料庫還是[LDAP](https://zh.wikipedia.org/wiki/LDAP "LDAP")伺服器,View 都會正確地顯示它們。==由於MVC模式的三個模組相互獨立,改變其中一個不會影響其他兩個,所以依據這種設計思想能構造良好的少互擾性的構件。== 此外,Controller 提高了應用程式的**靈活性**和**可配置性**。Controller 可以用來連線不同的 Model 和 View 去完成用戶的需求,也可以構造應用程式提供強有力的手段。給定一些可重用的 Model 、 View 和Controller 可以根據用戶的需求選擇適當的 Model 進行處理,然後選擇適當的的 View 將處理結果顯示給用戶。 ### 實現語言 * [MFC](https://zh.wikipedia.org/wiki/MFC) * [Java](https://zh.wikipedia.org/wiki/Java "Java") 平台企業版 (J2EE) * [.NET](https://zh.wikipedia.org/wiki/.NET_Framework) * [Windows](https://zh.wikipedia.org/wiki/Windows "Windows") Forms * Python:最常用的有 [Django](https://zh.wikipedia.org/wiki/Django "Django") 和 [TurboGears](https://zh.wikipedia.org/wiki/TurboGears "TurboGears")。 * [PHP](https://zh.wikipedia.org/wiki/PHP "PHP") ## GET 與POST差別? HTML Form 表單有兩種資料傳遞方式,分別為 GET 與 PSOT 這兩種,當填好表單資料並按下送出表單的按鈕之後,必須透過這兩種方式將資料送出到伺服器(Web Server),以下為兩種方式的 HTML Code 寫法。 ```htmlmixed= <form action="接收資料的程式" method="get"> ``` ```htmlmixed= <form action="接收資料的程式" method="post"> ``` :::info GET :Requests data from a specified resource POST : Submits data to be processed to a specified resource ::: ### 差異 * GET產生的URL地址可以被**Bookmarked**,而POST不可以。 * GET可以被瀏覽器主動**cached**,而POST不會,除非手動設置 * GET請求參數會被完整保留在**瀏覽器歷史記錄**里,而POST中的參數不會被保留 * Get的資料請求有**長度限制**,POST沒有限制 * GET參數通過**URL傳遞**,POST放在**HTTP Request body中** * 對於GET方式的請求,瀏覽器會把http header和data一併發送出去,伺服器響應200;對於POST,瀏覽器先發送header,伺服器響應100 continue,瀏覽器再發送data,伺服器響應200 ok。 The following table lists some other HTTP request methods: | Method|Description | | -------- | -------- | | HEAD | Same as GET but returns only HTTP headers and no document body | | PUT | Uploads a representation of the specified URI | | DELETE|Deletes the specified resource | | OPTIONS |Returns the HTTP methods that the se |CONNECT |Converts the request connection to a transparent TCP/IP tunnel | ### Restful API