前方高能!!!
由於協議本身比較枯燥,本篇文章原理概述內容可能會比較多,如果感到不適請繞行(〃'▽'〃)TCP/IP
概述
TCP/IP是Internet最基本的協議、Internet國際網際網路絡的基礎,由網路層的IP協議和傳輸層的TCP協議組成。
TCP/IP 定義了電子裝置如何連入因特網,以及資料如何在它們之間傳輸的標準。協議採用了4層的層級結構,每一層都呼叫它的下一層所提供的協議來完成自己的需求。
通俗而言:TCP負責發現傳輸的問題,一有問題就發出訊號,要求重新傳輸,直到所有資料安全正確地傳輸到目的地。而IP是給因特網的每一臺聯網裝置規定一個地址。
TCP/IP協議不是單純的兩個協議,是一組不同層次上的多個協議的組合,常稱為TCP/IP協議簇或者網際網路協議簇。
TCP/IP層次組合很難用OSI的七層模型來套用,它是OSI模型的濃縮,將原來的七層模型合併為四層協議的體系結構,自頂向下分別是應用層、傳輸層、網路層和網路介面層,沒有OSI參考模型的會話層和表示層,一般認為TCP/IP的會話和表示功能是在傳輸層或應用層上完成的。
下面的圖表試圖顯示不同的TCP/IP和其他的協議在最初OSI模型中的位置:
層數 | 名稱 | 舉例 |
---|---|---|
7 | 應用層 | HTTP、SMTP、SNMP、FTP、Telnet、SIP、SSH、NFS、RTSP、XMPP、Whois、ENRP |
6 | 表示層 | XDR、ASN.1、SMB、AFP、NCP |
5 | 會話層 | ASAP、TLS、SSH、ISO 8327 / CCITT X.225、RPC、NetBIOS、ASP、Winsock、BSD sockets |
4 | 傳輸層 | TCP、UDP、RTP、SCTP、SPX、ATP、IL |
3 | 網路層 | IP、ICMP、IGMP、IPX、BGP、OSPF、RIP、IGRP、EIGRP、ARP、RARP、 X.25 |
2 | 資料鏈路層 | 乙太網、令牌環、HDLC、幀中繼、ISDN、ATM、IEEE 802.11、FDDI、PPP |
1 | 物理層 | 線路、無線電、光纖、信鴿 |
TCP/IP不是一個單獨的協議,而是一個協議簇,是一組不同層次上的多個協議的組合。上面給出了OSI與TCP/IP模型對比、TCP/IP不同層次的協議。
- 網路介面層:有時也稱作資料鏈路層或鏈路層,通常包括作業系統中的裝置驅動程式和計算機中對應的網路介面卡。它們一起處理與電纜(或其他任何傳輸媒介)的物理介面細節。在TCP/IP協議簇中,鏈路層的協議比較多,它決定了網路形態,但很多都不是專門為TCP/IP設計的。常用的鏈路層協議包括:乙太網協議、PPP協議、幀中繼協議、ATM等。
- 網路層:IP層有時也稱作互連網層,處理分組在網路中的活動,在底層通訊網路的基礎上,完成路由、尋徑功能,提供主機到主機的連線。IP是盡力傳送的、不可靠的協議。在TCP/IP協議簇中,網路層協議包括IP協議(網際協議),ICMP協議(Internet互連網控制報文協議),ARP/RARP(地址解析/反向地址解析協議),以及IGMP協議(Internet組管理協議)。
- 傳輸層:主要為兩臺主機上的應用程式提供端到端的通訊。在TCP/IP協議簇中,有兩個不同的傳輸協議:TCP(傳輸控制協議)和UDP(使用者資料包協議),它們分別承載不同的應用。TCP協議提供可靠的服務,UDP協議提供不可靠但是高效的服務。
- 應用層:這一層負責具體的應用,比如HTTP訪問、FTP檔案傳輸、SMTP/POP3郵件處理等等。幾乎各種不同的TCP/IP實現都會提供下面這些通用的應用程式:遠端登入(Telnet)、檔案傳輸協議(FTP)、簡單郵件傳輸協議(SMTP)、簡單網路管理協議(SNMP)。
嚴格來講,分層模型的動機就是將各層的功能儘量獨立,每層的功能對另一層來說是透明的,只對通訊的另一端負責,為程式設計和診斷提供良好的層次隔離,然而實際情況並非如此,首先軟體程式設計上完全按照分層模型來做程式設計效率會降低,與其分層,不如按功能實現來模組化。其次,對於許多功能實現來說,必須實現兩層子間的互動,這又違背了當初的出發點,比如鏈路層在成幀時需要接收端的實體地址,該地址必須由網路層處理ARP地址解析才行,簡單地將ARP放在那一層都有些牽強。所以說,分層模型對於理解網路的抽象性是有益處的,它有助於指導網路入門,但並不是網路的精髓,只有結合具體的系統分析才有實際意義。
提到TCP就不得不說說TCP建立連線的三次握手了(~ ̄▽ ̄)~
TCP是面向連線的傳輸層協議,所謂面向連線就是在真正的資料傳輸開始前要完成連線建立的過程,否則不會進入真正的資料傳輸階段。
TCP的連線建立過程通常被稱為三次握手(three-way handshake),過程如下:
- 請求端(通常稱為客戶)傳送一個SYN段指明客戶打算連線的伺服器的埠,以及初始序號(ISN)。這個SYN段為報文段1。
- 伺服器發回包含伺服器的初始序號的SYN報文段(報文段2)作為應答。同時,將確認序號設定為客戶的ISN加1以對客戶的SYN報文段進行確認。一個SYN將佔用一個序號。
- 客戶必須將確認序號設定為伺服器的ISN加1以對伺服器的SYN報文段進行確認(報文段3)。 這三個報文段完成連線的建立。
斷開連線:一個TCP連線是全雙工(即資料在兩個方向上能同時傳遞),因此每個方向必須單獨進行關閉。當一方完成它的資料傳送任務後就傳送一個FIN來終止這個方向連線。當一端收到一個FIN,它必須通知應用層另一端已經終止了那個方向的資料傳送。所以TCP終止連線的過程需要四個過程,稱之為四次握手過程。
HTTP
HTTP協議即超文字傳送協議(Hypertext Transfer Protocol ),是Web聯網的基礎,也是手機聯網常用的協議之一,HTTP協議是建立在TCP協議之上的一種應用。
HTTP連線最顯著的特點是客戶端傳送的每次請求都需要伺服器回送響應,在請求結束後,會主動釋放連線。從建立連線到關閉連線的過程稱為“一次連線”。
http的請求
http請求由三部分組成,分別是:請求行、訊息報頭、請求正文
1、請求行以一個方法符號開頭,以空格分開,後面跟著請求的URI和協議的版本,格式如下:
Method Request-URI HTTP-Version CRLF
- Method表示請求方法
- Request-URI是一個統一資源識別符號
- HTTP-Version表示請求的HTTP協議版本
- CRLF表示回車和換行(除了作為結尾的CRLF外,不允許出現單獨的CR或LF字元)。
請求方法(所有方法全為大寫)有多種:
- GET: 請求獲取Request-URI所標識的資源
- POST: 在Request-URI所標識的資源後附加新的資料
- HEAD: 請求獲取由Request-URI所標識的資源的響應訊息報頭
- PUT: 請求伺服器儲存一個資源,並用Request-URI作為其標識
- DELETE: 請求伺服器刪除Request-URI所標識的資源
- TRACE: 請求伺服器回送收到的請求資訊,主要用於測試或診斷
- CONNECT: 保留將來使用
- OPTIONS: 請求查詢伺服器的效能,或者查詢與資源相關的選項和需求
應用舉例:
GET方法:在瀏覽器的位址列中輸入網址的方式訪問網頁時,瀏覽器採用GET方法向伺服器獲取資源
eg:GET /form.html HTTP/1.1 (CRLF)
POST方法要求被請求伺服器接受附在請求後面的資料,常用於提交表單。
eg:POST /reg.jsp HTTP/ (CRLF)
Accept:image/gif,image/x-xbit,... (CRLF)
...
HOST:www.guet.edu.cn (CRLF)
Content-Length:22 (CRLF)
Connection:Keep-Alive (CRLF)
Cache-Control:no-cache (CRLF)
(CRLF) //該CRLF表示訊息報頭已經結束,在此之前為訊息報頭
user=jeffrey&pwd=1234 //此行以下為提交的資料
HEAD方法與GET方法幾乎是一樣的,對於HEAD請求的迴應部分來說,它的HTTP頭部中包含的資訊與通過GET請求所得到的資訊是相同的。利用這個方法,不必傳輸整個資源內容,就可以得到Request-URI所標識的資源的資訊。該方法常用於測試超連結的有效性,是否可以訪問,以及最近是否更新。
http的響應
在接收和解釋請求訊息後,伺服器返回一個HTTP響應訊息。
HTTP響應也是由三個部分組成,分別是:狀態行、訊息報頭、響應正文
1、狀態行格式如下:
HTTP-Version Status-Code Reason-Phrase CRLF
其中,HTTP-Version表示伺服器HTTP協議的版本;Status-Code表示伺服器發回的響應狀態程式碼;Reason-Phrase表示狀態程式碼的文字描述。
狀態程式碼有三位數字組成,第一個數字定義了響應的類別,且有五種可能取值:
1xx:指示資訊--表示請求已接收,繼續處理
2xx:成功--表示請求已被成功接收、理解、接受
3xx:重定向--要完成請求必須進行更進一步的操作
4xx:客戶端錯誤--請求有語法錯誤或請求無法實現
5xx:伺服器端錯誤--伺服器未能實現合法的請求
常見狀態程式碼、狀態描述、說明:
200 OK //客戶端請求成功
400 Bad Request //客戶端請求有語法錯誤,不能被伺服器所理解
401 Unauthorized //請求未經授權,這個狀態程式碼必須和WWW-Authenticate報頭域一起使用
403 Forbidden //伺服器收到請求,但是拒絕提供服務
404 Not Found //請求資源不存在,eg:輸入了錯誤的URL
500 Internal Server Error //伺服器發生不可預期的錯誤
503 Server Unavailable //伺服器當前不能處理客戶端的請求,一段時間後可能恢復正常
eg:HTTP/1.1 200 OK (CRLF)
http的報頭
HTTP訊息由客戶端到伺服器的請求和伺服器到客戶端的響應組成。請求訊息和響應訊息都是由開始行(對於請求訊息,開始行就是請求行,對於響應訊息,開始行就是狀態行),訊息報頭(可選),空行(只有CRLF的行),訊息正文(可選)組成。
HTTP訊息報頭包括普通報頭
、請求報頭
、響應報頭
、實體報頭
。
每一個報頭域都是由名字+“:”+空格+值 組成,訊息報頭域的名字是大小寫無關的。
1、普通報頭
在普通報頭中,有少數報頭域用於所有的請求和響應訊息,但並不用於被傳輸的實體,只用於傳輸的訊息。
eg:
- Cache-Control 用於指定快取指令,快取指令是單向的(響應中出現的快取指令在請求中未必會出現),且是獨立的(一個訊息的快取指令不會影響另一個訊息處理的快取機制),HTTP1.0使用的類似的報頭域為Pragma。
- 請求時的快取指令包括:no-cache(用於指示請求或響應訊息不能快取)、no-store、max-age、max-stale、min-fresh、only-if-cached;
- 響應時的快取指令包括:public、private、no-cache、no-store、no-transform、must-revalidate、proxy-revalidate、max-age、s-maxage.
eg:為了指示IE瀏覽器(客戶端)不要快取頁面,伺服器端的JSP程式可以編寫如下:
response.sehHeader("Cache-Control","no-cache");
//response.setHeader("Pragma","no-cache");//作用相當於上述程式碼,通常兩者合用
這句程式碼將在傳送的響應訊息中設定普通報頭域:Cache-Control:no-cache
- Date普通報頭域表示訊息產生的日期和時間
- Connection普通報頭域允許傳送指定連線的選項。例如指定連線是連續,或者指定“close”選項,通知伺服器,在響應完成後,關閉連線
2、請求報頭
請求報頭允許客戶端向伺服器端傳遞請求的附加資訊以及客戶端自身的資訊。
Accept
Accept請求報頭域用於指定客戶端接受哪些型別的資訊。
eg:Accept:image/gif,表明客戶端希望接受GIF圖象格式的資源;
Accept:text/html,表明客戶端希望接受html文字。
Accept-Charset
- Accept-Charset請求報頭域用於指定客戶端接受的字符集。
- eg:Accept-Charset:iso-8859-1,gb2312.如果在請求訊息中沒有設定這個域,預設是任何字符集都可以接受。
Accept-Encoding
- Accept-Encoding請求報頭域類似於Accept,但是它是用於指定可接受的內容編碼。
- eg:Accept-Encoding:gzip.deflate.如果請求訊息中沒有設定這個域伺服器假定客戶端對各種內容編碼都可以接受。
Accept-Language
- Accept-Language請求報頭域類似於Accept,但是它是用於指定一種自然語言。
- eg:Accept-Language:zh-cn.如果請求訊息中沒有設定這個報頭域,伺服器假定客戶端對各種語言都可以接受。
Authorization
- Authorization請求報頭域主要用於證明客戶端有權檢視某個資源。當瀏覽器訪問一個頁面時,如果收到伺服器的響應程式碼為401(未授權),可以傳送一個包含Authorization請求報頭域的請求,要求伺服器對其進行驗證。
Host(傳送請求時,該報頭域是必需的)
- Host請求報頭域主要用於指定被請求資源的Internet主機和埠號,它通常從HTTP URL中提取出來的
- eg:
我們在瀏覽器中輸入:http://www.guet.edu.cn/index.html 瀏覽器傳送的請求訊息中,就會包含Host請求報頭域: Host:www.guet.edu.cn 此處使用預設埠號80,若指定了埠號,則變成:Host:www.guet.edu.cn:指定埠號
User-Agent
我們上網登陸論壇的時候,往往會看到一些歡迎資訊,其中列出了你的作業系統的名稱和版本,你所使用的瀏覽器的名稱和版本,這往往讓很多人感到很神奇,實際上,伺服器應用程式就是從User-Agent這個請求報頭域中獲取到這些資訊。User-Agent請求報頭域允許客戶端將它的作業系統、瀏覽器和其它屬性告訴伺服器。不過,這個報頭域不是必需的,如果我們自己編寫一個瀏覽器,不使用User-Agent請求報頭域,那麼伺服器端就無法得知我們的資訊了。請求報頭舉例:
- GET /form.html HTTP/1.1 (CRLF)
- Accept:image/gif,image/x-xbitmap,image/jpeg,application/x-shockwave-flash,application/vnd.ms-excel,application/vnd.ms-powerpoint,application/msword,/ (CRLF)
- Accept-Language:zh-cn (CRLF)
- Accept-Encoding:gzip,deflate (CRLF)
- If-Modified-Since:Wed,05 Jan 2007 11:21:25 GMT (CRLF)
- If-None-Match:W/"80b1a4c018f3c41:8317" (CRLF)
- User-Agent:Mozilla/4.0(compatible;MSIE6.0;Windows NT 5.0) (CRLF)
- Host:www.guet.edu.cn (CRLF)
- Connection:Keep-Alive (CRLF)
- (CRLF)
3、響應報頭
響應報頭允許伺服器傳遞不能放在狀態行中的附加響應資訊,以及關於伺服器的資訊和對Request-URI所標識的資源進行下一步訪問的資訊。
Location
- Location響應報頭域用於重定向接受者到一個新的位置。Location響應報頭域常用在更換域名的時候。
Server
- Server響應報頭域包含了伺服器用來處理請求的軟體資訊。與User-Agent請求報頭域是相對應的,例如:
- Server:Apache-Coyote/1.1
- WWW-Authenticate
- WWW-Authenticate響應報頭域必須被包含在401(未授權的)響應訊息中,客戶端收到401響應訊息時候,併傳送Authorization報頭域請求伺服器對其進行驗證時,服務端響應報頭就包含該報頭域。
- eg:WWW-Authenticate:Basic realm="Basic Auth Test!" //可以看出伺服器對請求資源採用的是基本驗證機制。
4、實體報頭
請求和響應訊息都可以傳送一個實體。一個實體由實體報頭域和實體正文組成,但並不是說實體報頭域和實體正文要在一起傳送,可以只傳送實體報頭域。實體報頭定義了關於實體正文(eg:有無實體正文)和請求所標識的資源的元資訊。
- Content-Encoding
Content-Encoding實體報頭域被用作媒體型別的修飾符,它的值指示了已經被應用到實體正文的附加內容的編碼,因而要獲得Content-Type報頭域中所引用的媒體型別,必須採用相應的解碼機制。Content-Encoding這樣用於記錄文件的壓縮方法,eg:Content-Encoding:gzip
- Content-Language
Content-Language實體報頭域描述了資源所用的自然語言。沒有設定該域則認為實體內容將提供給所有的語言閱讀 者。eg:Content-Language:da
- Content-Length
Content-Length實體報頭域用於指明實體正文的長度,以位元組方式儲存的十進位制數字來表示。
- Content-Type
Content-Type實體報頭域用語指明傳送給接收者的實體正文的媒體型別。
eg:Content-Type:text/html;charset=ISO-8859-1
Content-Type:text/html;charset=GB2312
- Last-Modified
Last-Modified實體報頭域用於指示資源的最後修改日期和時間。
- Expires
Expires實體報頭域給出響應過期的日期和時間。為了讓代理伺服器或瀏覽器在一段時間以後更新快取中(再次訪問曾訪問過的頁面時,直接從快取中載入,縮短響應時間和降低伺服器負載)的頁面,我們可以使用Expires實體報頭域指定頁面過期的時間。
eg:Expires:Thu,15 Sep 2006 16:23:12 GMT
socket
網路上的兩個程式通過一個雙向的通訊連線實現資料的交換,這個連線的一端稱為一個socket。
建立網路通訊連線至少要一對埠號(socket)。socket本質是程式設計介面(API),對TCP/IP的封裝,TCP/IP也要提供可供程式設計師做網路開發所用的介面,這就是Socket程式設計介面;HTTP是轎車,提供了封裝或者顯示資料的具體形式;Socket是發動機,提供了網路通訊的能力。
套接字(socket)是通訊的基石,是支援TCP/IP協議的網路通訊的基本操作單元。它是網路通訊過程中端點的抽象表示,包含進行網路通訊必須的五種資訊:連線使用的協議,本地主機的IP地址,本地程式的協議埠,遠地主機的IP地址,遠地程式的協議埠。
應用層通過傳輸層進行資料通訊時,TCP會遇到同時為多個應用程式程式提供併發服務的問題。多個TCP連線或多個應用程式程式可能需要通過同一個 TCP協議埠傳輸資料。為了區別不同的應用程式程式和連線,許多計算機作業系統為應用程式與TCP/IP協議互動提供了套接字(Socket)介面。應 用層可以和傳輸層通過Socket介面,區分來自不同應用程式程式或網路連線的通訊,實現資料傳輸的併發服務。
建立socket連線
建立Socket連線至少需要一對套接字,其中一個執行於客戶端,稱為ClientSocket ,另一個執行於伺服器端,稱為ServerSocket 。
套接字之間的連線過程分為三個步驟:伺服器監聽,客戶端請求,連線確認。
-
伺服器監聽:伺服器端套接字並不定位具體的客戶端套接字,而是處於等待連線的狀態,實時監控網路狀態,等待客戶端的連線請求。
-
客戶端請求:指客戶端的套接字提出連線請求,要連線的目標是伺服器端的套接字。為此,客戶端的套接字必須首先描述它要連線的伺服器的套接字,指出伺服器端套接字的地址和埠號,然後就向伺服器端套接字提出連線請求。
-
連線確認:當伺服器端套接字監聽到或者說接收到客戶端套接字的連線請求時,就響應客戶端套接字的請求,建立一個新的執行緒,把伺服器端套接字的描 述發給客戶端,一旦客戶端確認了此描述,雙方就正式建立連線。而伺服器端套接字繼續處於監聽狀態,繼續接收其他客戶端套接字的連線請求。