TCP與UDP:TCP提供可靠的服務UDP提供數據報. 二者都是端點協議。路由設備無論這個也不認識這個。路由設備只認識IP協議與包。可是TCP的包被放在IP上面,因此TCP必然是IP語義的收窄。TCP將IP的包語義轉化爲傳輸者語義由此創建傳輸服務。 html
TCP及如下的各層都是向機器的語義,是硬件相關的語義。而TCP以上是用戶語義,是源語義。從會話層開始全是與機器無關的語義。會話、表示、應用層全是用戶協議。因此http根本不符合OSI模型由於它講的仍然是鳥語。http頂多算個會話層協議。html纔是表示層協議。分佈式遠程調用協議iiop也是表示層協議。真正的應用層協議只能從真正的「應用」裏面去找。 前端
從物理層嚮應用層是一個語義逐漸收窄的過程。應用須要被表示,表示是會話的內容而會話又須要被傳輸,傳輸是在網絡上進行的因此必須是一個㒳絡元素。而網絡又是創建在數據鏈路上的。數據鏈路是電子設備。這樣串起整個7層的。 java
對程序員來講,,IP層與包都是隱藏的。看不見的。IP是協議實現者的工具,是武器不是程序員的菜。考慮網絡性能的話對它瞭解一下是能夠的,可是基本上跟咱們無關。Socket嚴格說是操做系統的東西像文件IO同樣,咱們用的是API。並非真正的「Socket」。因此java的socket應該是包了三層的一個API! 程序員
咱們真正寫程序,最好連socket也不要用由於它沒有會話層會很麻煩。除非你要的會話協議找不到不然不要在socket上直接寫程序,像web服務器同樣,你能夠在相似http同樣的協議上寫東西。事情上你能夠且應該在http server上作網絡編程! web
說一個例子。前端用FLASH作請求,多個模塊都有數據請求,用一個socket。多個消息順次發出可是響應亂序了。後發出的消息相應先到了。這樣就要作消息標識。比方分模塊分對象。固然也能夠建個鏈接池,把鏈接官起來待需分配。而後每次請求用不同的鏈接。可是這樣服務端就有多個鏈接形成服務器瞎忙或資源佔用。固然能夠不在意這個,可是會話始終是一個不可否認的需求。這塊工做始終是不能逃避的。而用HTTP把它包起來的好處是,它提供了一個會話界面。使事情變得簡單明瞭,即:會話確定是要在「會話」上進行的。而不是在「鏈接」上進行的。在鏈接上進行的那個東西叫會話。其他的東西都是創建在會話語義上的。即便你沒有明顯的會話層存在,語義的層次仍是在。這個叫語義分層。你放棄分層不表明你不分層。層次就在那裏。一直在語義裏。 編程
注意會話是兩端的事情。一方有「會話」不表明另外一方也有「會話」。因此你知道協議是什麼東西了。協議就是你們都知道它並遵循它。因而協議是一個繞不過的東西。因而我說不要用「裸」的socket。由於它沒有會話協議。會話就會亂掉。要有條理,還得要「協議」。必須有協議。固然有些程序不須要會話由於它的單次消息lifetime很長。好比文件傳輸。它是以傳輸而不是會話爲主要任務的,因此socket夠了。open一個socket傳過去就夠了沒有別的說法。 服務器
關於tcp的段與ip的分片,我認爲它們都是協議內部的事情只能看成協議特性考慮不能放大了看。ip分片不會向上表現或影響它可能經過影響ip服務的特性來影響上層協議但不會直接對上層編程產生影響。tcp段也是,它也是tcp內部的事情與tcp向上提供的服務也沒有格式上的關係。tcp向上提供的是一個流服務,while ip向上提供的就是一個ip服務。ip是tcp的工具,while tcp又是更上層的工具!咱們應該這樣來理解整個協議棧。 網絡
因此不存在什麼粘包這樣的事情也不存在組包這樣的事情,當你在用一個tcp你就應該知道你在用的是一個流服務。而當你在用一個udp,你就是在用一個數據報服務。這是你要忘掉ip。ip不爲你工做,ip爲tcp工做。它是經過爲tcp工做來爲你工做的。向讓它直接爲你工做的想法不合適也不可行那只是癡心妄想,是不存在的事情。存在的是tcp爲你在工做。你有的是tcp不是ip。這是正確的tcp哲學。其他都不是正道。 socket
因此寫網絡程序,瞭解tcp的傳輸特性纔是最重要的而不是別的事情。固然底層會對上層產生影響,可是你思考問題的思路仍是要依據正確的模型。tcp根本沒有包,爲何要說粘包組包這樣的東西?udp的確有個"報」但那也不是「包」,好比包會被拆掉而對於報這卻不可能發生。沒有這樣的事情。這對於理清編程思路是很是必要的。 tcp