http://blog.nickliu.cn/index.php/archives/category/ios
今兒是個還債的日子,沒錯,承諾了許久的網(wǎng)絡(luò)傳輸篇雖然沒有千呼萬喚,不過我還是厚著臉皮始出來,繼上兩篇文章總結(jié)了一下開發(fā)IM語音功能時所遇到的音頻問題,而今天就讓我們來看看這個讓我們看似近在眼前,確始終猶抱琵琶半遮面的網(wǎng)絡(luò)傳輸吧~不過在開始我先要提醒一下諸位看官,我們的本章的內(nèi)容中只是介紹網(wǎng)絡(luò)的基礎(chǔ)只是以及網(wǎng)絡(luò)協(xié)議部分的知識,針對于如何在IOS下應(yīng)用使用各種協(xié)議進(jìn)行開發(fā),我們將在IOS網(wǎng)絡(luò)開發(fā)應(yīng)用篇中詳細(xì)的講解,或許對于幾千字的純文字描述來說,講解各種協(xié)議以及一些網(wǎng)絡(luò)基礎(chǔ)知識會顯得非??菰铮嘈盼?,這幾千字的文章中是你最易于理解最全面最值得你品讀的,關(guān)于一個程序所應(yīng)具備的互聯(lián)網(wǎng)知識。
網(wǎng)絡(luò)一詞早已不是什么新鮮話題,不要說來看本文的技術(shù)型看官們,就連個小學(xué)生嘴里都能冒出幾句http,tcp等網(wǎng)絡(luò)協(xié)議的名稱,可網(wǎng)絡(luò)是怎么傳輸?shù)?,協(xié)議又是干嘛用的?恐怕這一問就要從念叨名詞的受眾人群中砍掉絕大部分的回答者了。沒錯從開頭看來大伙應(yīng)該就明白了,筆者又要從遠(yuǎn)古時期開始講解,別嫌我煩,做學(xué)問要刨根問底,沒有個打破沙鍋問到底的精神,就做不成大學(xué)問?,F(xiàn)在這個時代,是知識爆發(fā)的時代,也是知識競賽的時代,你懂個浮皮潦草,別人都懂沒意思,想要出類拔萃,就要為人所不能為,知人所不知,方可憑其一身學(xué)識,立一方事業(yè)。好了跑偏的話題到此為止,接下來,就讓我們從“遠(yuǎn)古時期”一步步來理解網(wǎng)絡(luò)傳輸?shù)母拍?、原理、最終到如何善用。
在計(jì)算機(jī)領(lǐng)域中,網(wǎng)絡(luò)就是用物理鏈路將各個孤立的工作站或主機(jī)相連在一起,組成數(shù)據(jù)鏈路,從而達(dá)到資源共享和通信的目的。我們用直觀一些的白話來說,可以認(rèn)為是看官與我之間架起一根管道,而通過這個管道把某個物體從一端仍到另一端去,這期中所用到的道具、動作以及雙方的通知準(zhǔn)備就是計(jì)算機(jī)網(wǎng)絡(luò)運(yùn)行的基礎(chǔ)模型。計(jì)算機(jī)網(wǎng)絡(luò)的創(chuàng)造者也是人,他們在創(chuàng)造這個跨時代產(chǎn)物的時候也是通過自身常識來判斷和設(shè)計(jì)的,或許這個架起管道的實(shí)例并不恰當(dāng)或具體,不過簡單的動作往往更能讓人容易理解。從計(jì)算機(jī)的角度說,計(jì)算機(jī)網(wǎng)絡(luò)常用的傳輸模式是遵循網(wǎng)絡(luò)七層協(xié)議(OSI),而這個協(xié)議就是將這個簡單的過程復(fù)雜化,以達(dá)到很多簡單過程無法達(dá)到的理想效果。說實(shí)話如果可以,我一直再絞盡腦汁改如何避開OSI來繼續(xù)講解,因?yàn)樗讓犹珡?fù)雜并且作為我們程序員并不需要取完全了解它,最重要的是。。。說來慚愧,筆者也不是那么了解這個七層協(xié)議,無法講解的面面俱到,但是,想到下面對于tcp、udp以及http等常用協(xié)議的講解,又不得不提到那么一點(diǎn),所以我在此設(shè)下伏筆,稍后我們會略有涉及,但出于不要誤人子弟的中心思想,本文不會詳解,如果又感興趣的看官自行詢問度娘,作為一代傲嬌弱受,她可謂是上知天文下曉地理,而對于網(wǎng)絡(luò)七層協(xié)議她更是專家中的專家
如果說網(wǎng)線、路由、網(wǎng)卡等硬件設(shè)備是我們之前所提到需要傳輸時架起的管子,那么作為程序員,我們更應(yīng)該關(guān)注的問題應(yīng)該是如何再錯綜復(fù)雜的管子之間找到要仍的那一根(要知道因特網(wǎng)連接的計(jì)算機(jī)是數(shù)以億計(jì)的?。绾胃嬖V對方我們要扔出物體了,如何扔出我們的物體,以及如何接到這個物體。以不至于東西仍錯了管子誤傷到無關(guān)的路人,或是東西已經(jīng)扔到對方臉上,他還不知道是什么。或許真正的人不會那么遲鈍,因?yàn)槿耸巧衿娴奶熳髦希畈豢伤甲h的大自然結(jié)晶,而計(jì)算機(jī)則不然,如果管子另一端是猶如計(jì)算機(jī)的機(jī)器人,那么你要是不以他理解的方式告訴他一下,真的就會砸到臉上都木有反應(yīng)??!
沒錯,將上面一段話用稍顯學(xué)術(shù)點(diǎn)的話語總結(jié)起來就是,數(shù)據(jù)行駛在路由、網(wǎng)卡、網(wǎng)線、無線信號之上,而我們程序員要做的是在數(shù)據(jù)出發(fā)前,出發(fā)后,以及接收前和接受后所做的一切準(zhǔn)備、判斷、解釋、執(zhí)行、保存等工作,這些工作可謂繁多復(fù)雜,無規(guī)矩不成方圓,如果每個程序員都按照自己想法去編寫,那么我想我在MSN上從這段發(fā)送一句你好之后,你在另一端可能看到的將會是我問候你家庭成員的骯臟語句,那么….后果將不堪設(shè)想不對么….為了避免這樣的錯誤發(fā)生,為了讓蒼老師的種子總是可以安全的發(fā)送到下一位基友的手中,并且保證他下載的不會是金剛葫蘆娃1080P的全集,于是眾多的網(wǎng)絡(luò)協(xié)議誕生了。
這里我們來深究一下,為什么網(wǎng)絡(luò)協(xié)議要叫協(xié)議?這個名字讓眾多剛接觸的人感到高不可攀,難以理解,簡單來說,就是產(chǎn)生了雖但厲的趕腳!回到正題,為什么網(wǎng)絡(luò)協(xié)議不叫網(wǎng)絡(luò)黃金合體?不叫網(wǎng)絡(luò)十萬個為什么?不叫網(wǎng)絡(luò)布拉布拉得痛呢?我們接著從現(xiàn)實(shí)的事物中來體會協(xié)議二字的意義,如果我現(xiàn)在接一個蓋樓房的項(xiàng)目,那么雇主要跟我談一個合同,從哪天到哪天讓我去招工,哪天到哪天開始動工打地基,哪天到哪天蓋樓,蓋到什么時候結(jié)款。那么這樣一個流程就是一個協(xié)議的達(dá)成。我們雙方遵循協(xié)議的規(guī)定,按照協(xié)議中制訂的計(jì)劃一步步完成。如果我在招工的時候自己跑去挖地基了,挖地基的時候又想要開始收錢,那么雇主會一個嘴巴把我扇回去招人,等到蓋樓的時候,我發(fā)現(xiàn)地基還沒挖完然后挖掘機(jī)等機(jī)器已經(jīng)不存在了,于是我只能帶著我剛招到的工人用雙手刨地基了。。。到最后就是整個工程被我弄得亂七八糟。沒錯,互聯(lián)網(wǎng)協(xié)議雖然功能大相徑庭,但是總的說來思路是一致的,我們該在什么位置做什么事,這就是協(xié)議所規(guī)定的,我們要做的是先按照需求選定協(xié)議,再按照協(xié)議的規(guī)范一步步將自己的需求完成,那么終于改說一下協(xié)議都有哪些了。
好吧,我們就先說一點(diǎn)我們平常常見的來舉例。TCP、UDP、FTP、HTTP我相信這些名詞大家早已耳熟能詳,但是,我首先要提醒各位的是,別光看他們的名字都是XXP或者是XXXP,并且都名字后面都加上了協(xié)議就把他們歸為一類,他們有著本質(zhì)的區(qū)別,具體的說,TCP、UDP是同一類,他們是位于網(wǎng)絡(luò)七層協(xié)議中的第四層傳輸層,再準(zhǔn)確一點(diǎn)他們是完成第四層傳輸層所指定的功能,也是位于我們計(jì)算機(jī)編程人員所接觸到的網(wǎng)絡(luò)七層協(xié)議中的最底層(前三層由硬件構(gòu)成),而FTP與HTTP他們完成的是網(wǎng)絡(luò)七層協(xié)議中第七層也就是最頂層的應(yīng)用層。還要提醒大家的是,雖然從字面上看第四層與第七層相距甚遠(yuǎn),而實(shí)際上,他們的跨度不是很大,更并非風(fēng)馬牛不相及,相反他們是緊緊相連的,比如,F(xiàn)TP其實(shí)就是基于TCP/IP協(xié)議而實(shí)現(xiàn)的文件傳輸協(xié)議。
我們從深到淺從計(jì)算機(jī)網(wǎng)絡(luò)是什么說到了網(wǎng)絡(luò)協(xié)議是什么有哪些,接下來我們需要換個順序,從淺到深,依次講講今天說到的這4個協(xié)議,第一個協(xié)議,我們先來說說我的諸位同事——php程序員們所最常接觸的http協(xié)議。
Http協(xié)議,全稱hypertext transport protocol, 中文名稱是超文本鏈接傳輸協(xié)議他詳細(xì)規(guī)定了瀏覽器和萬維網(wǎng)服務(wù)器之間互相通信的規(guī)則,通過因特網(wǎng)傳送萬維網(wǎng)文檔的數(shù)據(jù)傳送協(xié)議。他是用于從WWW服務(wù)器傳輸超文本到本地瀏覽器的傳送協(xié)議。它可以使瀏覽器更加高效,使網(wǎng)絡(luò)傳輸減少。它不僅保證計(jì)算機(jī)正確快速地傳輸超文本文檔,還確定傳輸文檔中的哪一部分,以及哪部分內(nèi)容首先顯示(如文本先于圖形)等。他誕生于上世紀(jì)九十年代初期,最初被廣泛應(yīng)用的是http0.9,但是它最為知名并且被沿用至今的就是http1.1。
http的特點(diǎn)主要由以下4點(diǎn)較為突出。
1、簡單快速:客戶向服務(wù)器請求服務(wù)時,只需傳送請求方法和路徑。請求方法常用的有GET、HEAD、POST。每種方法規(guī)定了客戶與服務(wù)器聯(lián)系的類型不同。由于HTTP協(xié)議簡單,使得HTTP服務(wù)器的程序規(guī)模小,因而通信速度很快。
2、靈活:HTTP允許傳輸任意類型的數(shù)據(jù)對象。正在傳輸?shù)念愋陀蒀ontent-Type加以標(biāo)記。
3、無連接:無連接的含義是限制每次連接只處理一個請求。服務(wù)器處理完客戶的請求,并收到客戶的應(yīng)答后,即斷開連接。采用這種方式可以節(jié)省傳輸時間。
4、無狀態(tài):HTTP協(xié)議是無狀態(tài)協(xié)議。無狀態(tài)是指協(xié)議對于事務(wù)處理沒有記憶能力。缺少狀態(tài)意味著如果后續(xù)處理需要前面的信息,則它必須重傳,這樣可能導(dǎo)致每次連接傳送的數(shù)據(jù)量增大。
簡單的來說,http協(xié)議架起的就是一根用戶和服務(wù)器之間的單向請求管道,用戶可以隨意向服務(wù)器訪問,并且要求服務(wù)器返回?cái)?shù)據(jù),但是并不允許服務(wù)器通過相同的方式,向客戶訪問,這種機(jī)制保證了客戶端與瀏覽器單次通話的效率,但是也存在著對于開發(fā)者而言不夠便捷的問題,當(dāng)然現(xiàn)如今我們已經(jīng)可以通過很多技術(shù)手段來達(dá)成服務(wù)器的主動相應(yīng),但是,這并非http本身具有的特性。同時Http協(xié)議的連接可以理解為即時性的,他每完成一次操作請求,需要重新進(jìn)行查找、準(zhǔn)備、傳輸、響應(yīng)、回傳、關(guān)閉等這個流程步驟,而不能像tcp協(xié)議那樣一次性連接之后可以持續(xù)的收發(fā)請求即時做出反應(yīng),等所有操作完成再關(guān)閉連接。所以,其實(shí)你在瀏覽網(wǎng)頁的時候,輸入一個網(wǎng)址或者點(diǎn)擊一個連接都是重新向服務(wù)器發(fā)送請求并要求返回?cái)?shù)據(jù),這樣的效率可以說從原理上來講并不高效,但是現(xiàn)在我們可以通過諸如緩存等方式來減少這種操作的弊端。Http協(xié)議中總共定義了八種方法來表明指定資源的不同操作方式。也就是對某個網(wǎng)址下的網(wǎng)頁,或者某個URL下的文件的八種不同操作。
OPTIONS
返回服務(wù)器針對特定資源所支持的HTTP請求方法。也可以利用向Web服務(wù)器發(fā)送”*”的請求來測試服務(wù)器的功能性。
OPTIONS請求方法的主要用途有兩個:
1、獲取服務(wù)器支持的HTTP請求方法;也是黑客經(jīng)常使用的方法。
2、用來檢查服務(wù)器的性能。例如:AJAX進(jìn)行跨域請求時的預(yù)檢,需要向另外一個域名的資源發(fā)送一個HTTP OPTIONS請求頭,用以判斷實(shí)際發(fā)送的請求是否安全。
HEAD
向服務(wù)器索要與GET請求相一致的響應(yīng),只不過響應(yīng)體將不會被返回。這一方法可以在不必傳輸整個響應(yīng)內(nèi)容的情況下,就可以獲取包含在響應(yīng)消息頭中的元信息。
客戶端可以使用HEAD請求來收集相關(guān)信息以確定如何操作該資源.例如,在IE中,如果一個OBJECT元素缺少TYPE參數(shù),瀏覽器就會發(fā)送一個HEAD請求,目標(biāo)URL為這個OBJECT元素的SRC屬性指定的URL.然后瀏覽器就能夠根據(jù)響應(yīng)中的Content-Type頭知道這是哪種類型的OBJECT.
GET
向指定的資源發(fā)出請求。獲取一個文檔,大部分唄傳輸?shù)臑g覽器的html,images,js,css,……都是通過get方法發(fā)出請求的。它是獲取數(shù)據(jù)的主要方法
注意:GET方法不應(yīng)當(dāng)被用于發(fā)布命令,更新數(shù)據(jù)庫,或任何明確的客戶端動作。其中一個原因是GET可能會被網(wǎng)絡(luò)蜘蛛等隨意訪問。
POST
向指定資源提交數(shù)據(jù)進(jìn)行處理請求(例如提交表單或者上傳文件)。數(shù)據(jù)被包含在請求體中。POST請求可能會導(dǎo)致新的資源的建立和/或已有資源的修改。
關(guān)于GET請求以及POST請求的安全問題
所謂安全,意味著操作用于獲取信息而非修改信息。換句話說,GET請求一般不應(yīng)該產(chǎn)生副作用。就是說,它僅僅是獲取資源信息,就像數(shù)據(jù)庫查詢一樣,不會修改,增加數(shù)據(jù),不會影響資源的狀態(tài)。這里安全的含義僅僅是指是否修改信息。
接下來,POST的安全性要比GET的安全性高。注意,這里所說的安全性和上面的GET提到的“安全”不是同個概念。上面“安全”的含義僅僅是不做數(shù)據(jù)修改,而這里安全的含義是真正的Security的含義,比如通過GET提交數(shù)據(jù),用戶名和密碼將銘文出現(xiàn)在URL上,因?yàn)榈顷戫撁嬗锌赡鼙粸g覽器緩存,其他人查看瀏覽器的歷史記錄,那么別人就可以拿到你的賬號和密碼了,除此之外,使用GET提交數(shù)據(jù)還可能會造成Cross-site request forgery攻擊,雖然我不知道它到底是什么攻擊。。。喜歡研究“如何不使用菜刀做菜而去殺人”的童鞋請自行百度“跨域偽造請求”。
PUT
通常用于向服務(wù)器發(fā)送請求,如果URI 不存在,則要求服務(wù)器根據(jù)請求創(chuàng)建資源,如果存在,服務(wù)器就接受請求內(nèi)容,并修改URI資源的原始版本。
關(guān)于POST與PUT的區(qū)別
POST請求的URI表示處理該封閉實(shí)體的資源,該資源可能是個數(shù)據(jù)接收過程、某種協(xié)議的網(wǎng)關(guān)、或者接收注解的獨(dú)立實(shí)體。然而,使用PUT請求對服務(wù)器操作的情況下,如果是要上傳文件,則需要確定服務(wù)器上尚無重復(fù)的文件名,并且生成URI而后提交請求,如果該文件已經(jīng)存在,則會出現(xiàn)被替換的情況,即使服務(wù)器做出判斷判別出當(dāng)前文件已存在,針對PUT請求,服務(wù)器也無法修改PUT請求當(dāng)前所要操作的URI,智能拒絕用戶的請求并且讓用戶重新發(fā)送該請求。
DELETE
請求服務(wù)器刪除Request-URI所標(biāo)識的資源。
在服務(wù)器接收到DELETE請求對某個URI的刪除請求后,服務(wù)器并不會馬上對其進(jìn)行操作,即使客戶端接收到的了200 OK信息的返回碼,也只是代表服務(wù)器已經(jīng)成功接收到該請求,具體操作則由服務(wù)器端完成。
TRACE(追溯)
回顯服務(wù)器收到的請求,主要用于測試或診斷。
TRACE和TRACK是用來調(diào)試web服務(wù)器連接的HTTP方式。
支持該方式的服務(wù)器存在跨站腳本漏洞,攻擊者可以利用此漏洞獲得合法用戶的私人信息。
CONNECT
HTTP/1.1協(xié)議中預(yù)留給能夠?qū)⑦B接改為管道方式的代理服務(wù)器
以上就是Http協(xié)議的八種請求,也是通過http協(xié)議與服務(wù)器溝通的所有方法,如今http協(xié)議被大量的應(yīng)用在萬維網(wǎng)領(lǐng)域也就是我們常說的web開發(fā)之中,但不代表http協(xié)議只能使用在web端,比如手機(jī)應(yīng)用之中,也存在很多使用http協(xié)議與服務(wù)器建立溝通的。比如比如百度地圖API,新浪微博App,比如人人網(wǎng)手機(jī)端,比如我們的三姑……
首先,我需要感謝看官您讀到了這里,這屬實(shí)不易,我想如果您真的是用心讀到此處估計(jì)會問,你洋洋灑灑寫了2000多字的http協(xié)議,可它跟你之前所說的架起一根管道對仍實(shí)物的比方好像完全沒什么關(guān)系,bingo!全中!就是這樣,http協(xié)議的運(yùn)作模式的確和之前的比喻不太相符合,如果硬要做一個比方的話,那么服務(wù)器就相當(dāng)于棒球中的接球手,而客戶端則相當(dāng)于投球手,每次當(dāng)客戶端投出一個球之后,服務(wù)器都會告訴你這是個好球還是壞球,當(dāng)然也有可能是被本壘打了。。。之所以要把http放到第一個還講這么多,是因?yàn)樗_確實(shí)實(shí)是我們在日常應(yīng)用中最容易接觸到的協(xié)議,比如你輸入任何網(wǎng)址之前先打上的http://。好吧,讓我們回到講解http協(xié)議之前,也就是管道對仍物品的例子中,沒錯,接下來我們要說的就是與此例非常相近的FTP協(xié)議
FTP協(xié)議全稱File Transfer Protocol,中文名稱文件傳輸協(xié)議。它使用 TCP 生成一個虛擬連接用于控制信息,然后再生成一個單獨(dú)的 TCP 連接用于數(shù)據(jù)傳輸。文件傳輸協(xié)議是TCP/IP網(wǎng)絡(luò)上兩臺計(jì)算機(jī)傳送文件的協(xié)議FTP是在TCP/IP網(wǎng)絡(luò)和INTERNET上最早使用的協(xié)議之一,它屬于網(wǎng)絡(luò)協(xié)議組的應(yīng)用層。FTP客戶機(jī)可以給服務(wù)器發(fā)出命令來下載文件,上傳文件,創(chuàng)建或改變服務(wù)器上的目錄.
沒錯,就如同他的名字一樣,F(xiàn)TP是專門用于文件傳輸?shù)膮f(xié)議,而就像我之前說過的那樣它的底層是基于TCP協(xié)議的。與http的模式不同,如果想要通過他來完成數(shù)據(jù)的傳輸,那么我們首先要做的第一步是先建立連接,而非直接對某個服務(wù)器發(fā)送請求。FTP有兩種使用模式:主動和被動。主動模式要求客戶端和服務(wù)器端同時打開并且監(jiān)聽一個端口以建立連接。在這種情況下,因?yàn)楸仨氶_放一個隨機(jī)的端口以建立連接,當(dāng)防火墻存在時,客戶端很難過濾處于主動模式下的FTP流量。所以,創(chuàng)立了被動模式。被動模式只要求服務(wù)器端產(chǎn)生一個監(jiān)聽相應(yīng)端口的進(jìn)程,這樣就可以繞過客戶端安裝了防火墻的問題。
一個主動模式的FTP連接建立要遵循以下步驟:
客戶端打開一個隨機(jī)的端口(端口號大于1024,在這里,我們稱它為x),同時一個FTP進(jìn)程連接至服務(wù)器的21號命令端口。此時,源端口為隨機(jī)端口x,在客戶端,遠(yuǎn)程端口為21,在服務(wù)器。
客戶端開始監(jiān)聽端口(x 1),同時向服務(wù)器發(fā)送一個端口命令(通過服務(wù)器的21號命令端口),此命令告訴服務(wù)器客戶端正在監(jiān)聽的端口號并且已準(zhǔn)備好從此端口接收數(shù)據(jù)。這個端口就是我們所知的數(shù)據(jù)端口。
服務(wù)器打開20號源端口并且建立和客戶端數(shù)據(jù)端口的連接。此時,源端口為20,遠(yuǎn)程數(shù)據(jù)端口為(x 1)。
客戶端通過本地的數(shù)據(jù)端口建立一個和服務(wù)器20號端口的連接,然后向服務(wù)器發(fā)送一個應(yīng)答,告訴服務(wù)器它已經(jīng)建立好了一個連接。
被動模式FTP:
為了解決服務(wù)器發(fā)起到客戶的連接的問題,人們開發(fā)了一種不同的FTP連接方式。這就是所謂的被動方式,或者叫做PASV,當(dāng)客戶端通知服務(wù)器它處于被動模式時才啟用。
在被動方式FTP中,命令連接和數(shù)據(jù)連接都由客戶端發(fā)起,這樣就可以解決從服務(wù)器到客戶端的數(shù)據(jù)端口的入方向連接被防火墻過濾掉的問題。
當(dāng)開啟一個 FTP連接時,客戶端打開兩個任意的非特權(quán)本地端口(N > 1024和N 1)。第一個端口連接服務(wù)器的21端口,但與主動方式的FTP不同,客戶端不會提交PORT命令并允許服務(wù)器來回連它的數(shù)據(jù)端口,而是提交 PASV命令。這樣做的結(jié)果是服務(wù)器會開啟一個任意的非特權(quán)端口(P > 1024),并發(fā)送PORT P命令給客戶端。然后客戶端發(fā)起從本地端口N 1到服務(wù)器的端口P的連接用來傳送數(shù)據(jù)。
對于服務(wù)器端的防火墻來說,必須允許下面的通訊才能支持被動方式的FTP:
從任何大于1024的端口到服務(wù)器的21端口 (客戶端的初始化連接)
服務(wù)器的21端口到任何大于1024的端口 (服務(wù)器響應(yīng)到客戶端的控制端口的連接)
從任何大于1024端口到服務(wù)器的大于1024端口 (客戶端初始化數(shù)據(jù)連接到服務(wù)器指定的任意端口)
服務(wù)器的大于1024端口到遠(yuǎn)程的大于1024的端口(服務(wù)器發(fā)送ACK響應(yīng)和數(shù)據(jù)到客戶端的數(shù)據(jù)端口)
好吧,我知道以上這些雖然足夠準(zhǔn)確無誤,但是它會讓人感覺頭暈?zāi)垦?,什么是端口?哪來的PORT和PASV?讓我們用通俗一些的話語來重新描述一遍整個過程。
首先,F(xiàn)TP下載模式的確立需要一個FTP服務(wù)器和一個客戶端,主動模式中,客戶端會按照指示找到一個FTP服務(wù)器,如果連接成功了,客戶端會先向服務(wù)器端發(fā)送一個指令,這個指令包含的內(nèi)容大致是你的所在位置。
接下來就像我們之前舉的例子一樣,當(dāng)管道架到另一頭之后,對方會告訴你,你的管道已經(jīng)在我手里了,可以準(zhǔn)備發(fā)東西了。此時的FTP服務(wù)器就會回頭跟客戶端打個招呼,“嘿,兄弟,你找到我了”,而當(dāng)前這根管道并非我們用來互扔物品的管道,他用來傳遞一些命令,這就像你發(fā)了個不會上門送件的快遞給朋友,與此同時你還要先打電話告訴他一下,“別忘了取郵局取快件”那么現(xiàn)在這根管道就相當(dāng)于你的電話。你可以在其中傳達(dá)各種信息及命令,比如你想要通過哪個物流來完成這次快遞,順豐還是圓通?再比如你要傳輸?shù)奈募鞘裁?,以及你是誰等等等等。
還記得我們第一步中發(fā)給服務(wù)器的那個地址么?沒錯是你的地址,當(dāng)服務(wù)器向你打過招呼后會緊接著向你之前所給出的地址發(fā)出一個連接,這個連接管道就是用來傳輸文件的管道了,而作為客戶端在成功連接之后你也應(yīng)該用同樣的方式回頭再打個招呼,“嘿,你真聰明,沒錯管道送過來了!”而這就是整個主動FTP連接的建立過程,在這之后你就可以與連接完畢的FTP服務(wù)器進(jìn)行文件收發(fā)了。但是我們的過程中有個讓人不太滿意的地方,是的,當(dāng)服務(wù)器想你的機(jī)器進(jìn)行訪問的時候,可能你還沒接到管道,就被自己家的門衛(wèi)給轟跑了,因?yàn)殚T衛(wèi)覺得他來歷不明,竟然還要想連一根管子進(jìn)小區(qū),沒錯像這樣可惡的家伙可能你的防火墻門衛(wèi)每天都會轟出去很多個~因?yàn)橛泻芏嗉一锵朐谀悴恢榈那闆r下通過一根根管道在你的家中行竊!
當(dāng)然問題都會又解決的方法,這就是被動FTP,它與主動FTP的不同的地方就是,你在連接服務(wù)器之后并不會發(fā)給他地址,讓它直接來找你,而只是告訴他“嘿,伙計(jì),我可算找到你了,等下哈,我馬上把管道牽過來!”然后服務(wù)器就會乖乖的把一個約定地址回發(fā)給你,當(dāng)然這個地址會與你剛找到他的那個不同,那是一個準(zhǔn)備要簡歷傳輸管道的地址。接下來客戶端要做的就是按照接到的地址再去連接一次服務(wù)器,這樣傳輸?shù)墓艿谰图芎昧?,同時你的門衛(wèi)也不會像對待那些歹徒一樣趕走服務(wù)器了。
好了,F(xiàn)TP就介紹到這里,或許我換了一種解釋方法之后你明白了FTP是怎么運(yùn)作的了,可是依然不了解什么是端口,沒關(guān)系,接下來我們將要要更深入一層,解一下TCP/IP協(xié)議,與UDP一樣它是位于軟件所涉及到最低層的網(wǎng)絡(luò)協(xié)議,而在這個過程中,我不只要告訴你什么是端口號,還要告訴你很多FTP和TCP他們最大的區(qū)別。
TCP全稱Transmission Control Protocol中文名,傳輸控制協(xié)議 ,TCP是一種面向連接(連接導(dǎo)向)的、可靠的、基于字節(jié)流的運(yùn)輸層(Transport layer)通信協(xié)議。而我們之前講到的TCP/IP準(zhǔn)確的來說是不完全相同的,因?yàn)門CP只是一部分,而后續(xù)的IP是另一部分
如果你還聽說過TCP/IP4,TCP/IP6的話其實(shí)別把他們之間的TCP分開看因?yàn)槟鞘且粋€東西,不同的其實(shí)是IP4和IP6,IP4中規(guī)定IP地址長度為32,即有232-1(符號表示升冪,下同)個地址;而IP6中IP地址的長度為128,即有2^128-1個地址。說實(shí)話我們或許不應(yīng)該談?wù)撎嚓P(guān)于IP的內(nèi)容,所以我只把IP4和IP6之間的區(qū)別列出了一點(diǎn),因?yàn)镮P他更傾向于網(wǎng)絡(luò)七層協(xié)議中的第三層,他的作用就是用于表示每臺計(jì)算機(jī),在一個局域網(wǎng)或廣域網(wǎng)或任何一個網(wǎng)絡(luò)中的物理地址,相當(dāng)于一臺計(jì)算機(jī)的門牌號,當(dāng)然這是電子門牌號,所以設(shè)置與更換起來可能讓你覺得沒有實(shí)際的門牌號那么困難,起碼你不用找有關(guān)當(dāng)局申請或協(xié)商,但是作用其實(shí)是一樣的——都是讓別人來找到你的位置。
好了關(guān)于IP我們就說這么多,現(xiàn)在回頭我們來說說TCP,前面說過,TCP通訊協(xié)議是面向連接的,可靠的,基于字節(jié)流的運(yùn)輸層通信協(xié)議,那么這一連串的名頭都代表著什么?我們逐一講解。
首先要說到的就是面向連接,說到這個名詞我們就得說說與它向?qū)?yīng)的一個名詞面向無連接, 其實(shí)我們通過http與FTP就可以看出二者的區(qū)別,當(dāng)然我這么說肯定會挨噴但是為了有助于各位理解我還是要說,http起碼從操作上來講,讓你感覺,不管服務(wù)器是否開啟,是否接受,我都只管發(fā)送我的請求,并不需要先向服務(wù)器確認(rèn)什么,即時服務(wù)器是關(guān)閉的,沒有啟動的,或者是網(wǎng)絡(luò)斷開的,對于我們客戶端來說該發(fā)送數(shù)據(jù)依然可以發(fā)送,當(dāng)然不過是服務(wù)器接不到嘛。但是FTP則不然,我們在真正發(fā)送數(shù)據(jù)之前需要先跟FTP服務(wù)器進(jìn)行連接通信,當(dāng)一系列的通信完成之后我們才可以做一系列傳輸數(shù)據(jù)等工作。這就是二者的區(qū)別。但是我必須要澄清,Http協(xié)議的底層雖然不是全部,但是依然主要依靠TCP的面向連接來完成的,而真正面向無連接的協(xié)議是UDP,關(guān)于這方面的知識,有興趣的童鞋可自行百度。
面向連接和面向無連接之間二者的區(qū)別我們理解了,可以確定的是,面向無連接協(xié)議傳輸速度要比面向連接的傳輸速度快很多,非常多,但也僅限于你的網(wǎng)絡(luò)帶寬之內(nèi),同時他還存在著很多不安因素,就像之前的比喻,如果我把管道加載一個機(jī)器人面前并且毫無前兆的就通過管道向他仍各種物品,那么結(jié)果就是砸到他臉上他都會置之不理。而再實(shí)際開發(fā)中,諸如此類的問題就如繁星一樣,躲到你忘記幾個都不會發(fā)現(xiàn)。。。所以說TCP協(xié)議是可靠的。
最后我們來說說什么是基于字節(jié)流的,字節(jié)我們很好理解,計(jì)算機(jī)中一切的存儲內(nèi)容,不論是內(nèi)存還是內(nèi)盤之中的存儲信息都是通過01機(jī)械碼來實(shí)現(xiàn)的,而每8位的01機(jī)械碼所組成的就是1字節(jié),以此向上的單位千字節(jié)就是KB,1024字節(jié)等于1KB,當(dāng)然在不同系統(tǒng)下?lián)Q算進(jìn)制不一樣,比如MAC系統(tǒng)下就是1000進(jìn)制,而之后的MB,GM,TB我相信你們都懂的- -而流就是不包含邊界數(shù)據(jù)的連續(xù)數(shù)據(jù)流,字節(jié)流我們從字面分析來看,一長串以字節(jié)為單位組成的不包含邊界數(shù)據(jù)的連續(xù)數(shù)據(jù)流。
如果我們要使用TCP協(xié)議來傳輸數(shù)據(jù)的話就得先確認(rèn)一個需要鏈接的對象,請注意我這里的用詞,并非服務(wù)器也非客戶端,沒錯TCP的連接建立,從協(xié)議本身來講并沒有服務(wù)器或者客戶端一說,他只是將兩個IP地址的計(jì)算機(jī)相連接起來,而我們需要的知識對方的IP地址,可是問題來了,或者我的服務(wù)器上并不只是運(yùn)行一個服務(wù)器端程序,有人訪問我的時候我該如何區(qū)分這些訪問信息分配給不同的程序呢?沒錯,這里我們就用到了套接字socket它與我們之前總是提到的端口號密不可分。
socket的英文原義是“孔”或“插座”。作為4BDS UNIX的進(jìn)程通信機(jī)制,取后一種意思。通常也稱作”套接字”,用于描述IP地址和端口,是一個通信鏈的句柄。常用的socket套接字有3種,而我們通過TCP協(xié)議所使用的就是流套接字(SOCK_STREAM)。而我們之前所說的端口號就是給予不同套接字所綁定的唯一的編號ID,取值范圍再0-65535之間,而前1024個端口是被各系統(tǒng)所占用內(nèi)部定義使用的換而言之就是我們在開發(fā)應(yīng)用程序分配端口號是要分配編號在1024以上的。而我們之前再FTP舉例中所提及的20端口號和21端口號就是特列,他們就是被系統(tǒng)所分配專門用于FTP傳輸?shù)亩丝谔枴?/p>
通常一個基于TCP協(xié)議的客戶端與服務(wù)器端的流程如下:
服務(wù)器程序開啟,同時監(jiān)聽某個指定好的,大于1024的端口號
客戶端啟動,并且按照服務(wù)器的IP與端口號向服務(wù)器訪問
服務(wù)器接到鏈接請求,鏈接接連成功,并且向客戶端返回一個鏈接成功的返回包
以上就是一個服務(wù)器與客戶端之間最簡單的連接建立的過程。
在創(chuàng)建連接之后我們要做的就是開始收發(fā)數(shù)據(jù),連接一旦創(chuàng)建第一件事情就是開啟一個無線性的循環(huán)/等待的的過程,不論是客戶端還是服務(wù)器端都要讓socket不停的接收數(shù)據(jù),哪怕根本沒有數(shù)據(jù)。這樣是為了再你需要向?qū)Ψ桨l(fā)送數(shù)據(jù)時,你只需要將需要發(fā)送的數(shù)據(jù)寫入數(shù)據(jù)流,那么對方就可以讀到你所寫入的內(nèi)容了,別高興的太早,這一切并沒有看起來的那么簡單。
按邏輯來說在建立連接之后,除非手動關(guān)閉,否則連接理論上與程序邏輯中會一直判定為該連接存在,但實(shí)際上我們需要通過很多手段來確認(rèn)連接是否正常。通常我們使用心跳包的方式來確認(rèn)連接的正常性,所謂的心跳包就是每間隔固定時間,從客戶端向服務(wù)器端發(fā)送的一個固定的數(shù)據(jù)包,服務(wù)器則會根據(jù)受到包的內(nèi)容判斷出這個數(shù)據(jù)包是個心跳包,同時也返回給客戶端一個信息,以讓客戶端得知連接正常無誤。以繼續(xù)進(jìn)行連接操作,又很多情況會導(dǎo)致程序邏輯上的連接狀態(tài)與實(shí)際的連接狀態(tài)不同,所以當(dāng)客戶端長時間接收不到心跳包的返回時我們就需要對程序的邏輯做出一定的修改,以避免嚴(yán)重錯誤的發(fā)生。
除此之外,我們還要判斷數(shù)據(jù)是否完全發(fā)送/接受,而且對于數(shù)據(jù)的處理也會面臨很多問題,因?yàn)門CP協(xié)議是基于字節(jié)流傳輸?shù)乃詳?shù)據(jù)并沒有開頭與結(jié)束之分,甚至如果一口氣連續(xù)發(fā)送幾個文件的話,我們在另一端接收到信息時甚至無法分清有幾個文件?他們都多長?這些都不知道,只是收到了一長串很長很長的字節(jié)流。
就如上面所說的,使用TCP協(xié)議是通過系統(tǒng)最底層的網(wǎng)絡(luò)傳輸協(xié)議來傳輸數(shù)據(jù),如果說http協(xié)議和ftp協(xié)議是定義了如何接收信息和如何區(qū)分信息以及傳輸信息的格式。那么tcp完成的就是確立目標(biāo)位置,并將數(shù)據(jù)統(tǒng)一化之后發(fā)送到目標(biāo)位置。直接通過tcp協(xié)議進(jìn)行開發(fā)可以達(dá)到最理想的面向連接協(xié)議傳輸效果,相對而言的我們需要付出更多的精力去編碼,用大量的代碼來維護(hù)鏈接的安全,在保證他的健壯性的同時,還要設(shè)定數(shù)據(jù)的分割以及接收的方式,等等等等,好吧,如果我說道這里你就覺得復(fù)雜了,我只想提醒你,后面還有UDP呢。。。。。。
好了今天天的內(nèi)容就到這里吧。。。已經(jīng)洋洋灑灑寫了近萬字。。。我如果非要把UDP也講完,估計(jì)也沒有童鞋能夠看完了,對于UDP我已經(jīng)不打算再此為大家繼續(xù)講解了,因?yàn)樗膬?nèi)容其實(shí)前面我們已經(jīng)提得差不多了,而關(guān)于具體的詳細(xì)內(nèi)容,請有心得童鞋自行百度吧,我們下篇文章將介紹,如何在IOS系統(tǒng)下使用http和tcp兩種方式的網(wǎng)絡(luò)傳輸。好吧各位看官,我們下期見。