本章是‘網絡是怎麼鏈接的--讀後感’第二章
前言
本章是系列博客的第二章;第一章講數據發送的場景;第二章主要講敘消息是如何發送出去的.web
實現需求
消息發送出去須要四部瀏覽器
- 建立套接字;
-
鏈接服務器創建管道;緩存
- 接收數據;
- 與服務器斷開鏈接並刪除套接字;
- IP與以太網在包收發過程當中的做用;
- 數據包轉換成電/光信號發送;
- 補充:UDP協議如何進行包的收發操做。
![](http://static.javashuo.com/static/loading.gif)
正文
第一章介紹了數據傳輸的的場景;本章講結合第五章具體闡述在用戶端電腦及服務器上數據是如何收發的。在瀏覽器上http協議經過解析用戶輸入網址得到http的消息,實際數據在網絡上傳播並不是以消息傳播的,而是經過數據包傳播;消息轉變爲數據包的過程是經過協議棧來實現的,先看個終端協議棧模型圖,該圖具備層級結構,上級向下一級指派工做,數據在終端上處理大概就是經過這個層級來實現:服務器
![](http://static.javashuo.com/static/loading.gif)
補充下:操做系統協議棧內的協議衆多並不是只有tcp和udp協議;不一樣的業務場景使用協議可能不一樣;大部分web通訊都是使用的tcp協議,tcp最典型功能是包傳輸具備確認機制不丟包;udp主要使用於傳輸的數據較短無需對包進行分隔時。網絡
數據就是經過上圖環節在電腦上進行處理的;主要有四步:socket
1、建立套接字tcp
套接字是對存了數據傳輸的一些控制信息,IP地址,端口的內存和數據的泛稱;能夠抽象成一張存了數據傳輸起點,終點位置信息,及數據傳輸控制操做信息的表;協議棧就是根據套接字的信息來控制數據傳輸的;通常會存本機網卡IP和端口,目的地的IP和端口,通訊的狀態信息,建立套接字的進程pid。套接字在消息收發過程當中操做以下:spa
![](http://static.javashuo.com/static/loading.gif)
套接字在消息收發過程當中的做用如圖:操作系統
- 應用程序經過調用Socket庫的socket方法建立套接字,計算出的套接字經過一個變量描敘符存入內存中;
- 而後經過調用Socket庫的connect方法創建和服務器套接字的鏈接;
- 調用write方法將http消息傳給協議棧(tcp);
- 在服務器傳數據過來時tcp協議棧經過套接字的控制信息調用操做系統的read方法將響應數據傳給應用程序的緩存區;
- 在客戶端/服務端都可經過套接字控制信息調用操做系統close方法,斷開鏈接;
二和3、與服務器鏈接,創建數據傳輸通道,並傳輸數據視頻
鏈接其實是通訊雙發交換控制信息,除了套接字的控制信息,協議包頭部自己也存在控制鏈接的控制信息;所以雙方要交換控制信息,雙方就必須都具備套接字;客戶端套接字建立上方已經講了,服務器的套接字在服務器初始化時就建立好了,一直處於等待鏈接階段,所以只須要協議棧的tcp協議向服務端發起請求交換這兩部分的控制信息便可;實際過程以下:
- 應用程序調用Socket庫的connect方法;這個方法裏面含有‘應用程序套接字的描敘符,服務器的IP和端口’等參數;經過這個方法將這些控制信息傳給協議棧;
- http生成的消息會存放在發送緩衝區;tcp協議對數據長度有約束,會將數據分割成合法的小段;並在數據段前加上tcp頭部;
- 協議棧根據得到的控制信息;將控制信息寫入tcp包的頭部,含有接收方的IP,接受方端口(經過請求地址和默認端口能夠知道,套接字和端口是關聯的,能定位服務器鏈接的套接字)
- 而後協議棧再將tcp包給IP模塊委託IP將包發送出去;IP在包前面加上IP頭(裏面含發送方的IP地址)和mac頭,mac頭是根據目的地IP經過arp計算出來的,。。。。
- 服務器接收到包;根據包的控制信息判斷出是發給它的包,經過解析tcp包頭部的控制信息找到須要創建鏈接的套接字;
- 並將收到的包的tcp頭部中的控制信息提取出來,同步到他的套接字中;因爲客戶端發送過來的第一段tcp包的syn(tcp頭部字段,創建鏈接時爲了使得兩端進行確認的字段)爲1;所以知道是來創建鏈接的包,服務端進行響應,響應有應答機制ack(tcp頭部參數),用來確認收到了包;
- 服務端以相同的操做發送鏈接的控制的包;客戶端收到包後;根據解析的頭信息確認到syn爲1;知道是服務端發送過來交換控制的包;後將收到的包的控制信息同步到應用程序套接字中,並進行應答確認收到了包,至此就創建了信息傳輸的通道;
- 第二部在發送緩衝區,tcp將http消息切割成了小的數據包;在接收方同時會有接受緩衝區,因爲tcp頭部含有每一個包的序號,所以根據序號就能在接收緩衝區最後將包組裝還原成原來的數據;
- tcp最強大的功能,就是數據傳輸過程當中能保證不丟包,這是經過tcp包的序號和應答的包的ack來肯定的;簡單說就是tcp發送的包會在頭部帶有序列號,接收方接收後會根據序列號計算出ack,而後在響應時會將ack發送給發送方,發送方就能根據收到響應的ack來肯定包有沒有正常接收,若是ack沒有或者有誤,就從新發送包;
- 補充:ack是tcp協議的一種確認機制;實際使用時常和窗口更新一塊兒傳輸;窗口更新是指,在接收方會有一個接收緩衝區,當接受的數據沒被應用程序使用前會存在這裏,窗口大小就是接受緩衝區剩餘容量的大小;將多個ack的響應和窗口更新消息一塊兒發送給發送方,能夠減少網絡中傳輸的包的數量減小帶寬,同時接收方接受到窗口信息,就能有效控制數據包的發送;
- 創建鏈接傳輸數據包並非終點;接收方接受的數據包是存放在接收緩衝區,事實是在發起數據請求時應用程序就調用了Socket庫的read方法建立了一個事務將接受緩衝區的數據傳給應用程序,因爲數據響應須要時間這個事務是暫時先掛起的,一旦響應的數據傳到緩衝區就激活了這個事務將數據傳給應用程序;
- 補充:http生成的消息是應用程序經過Socket庫的write方法傳到發送緩衝區的;
4、斷開與服務器的鏈接,並刪除套接字
應用程序判斷數據傳輸完了就會執行斷開操做;原則上客戶端和服務端均可以先斷開,在http1.0中是服務端先斷開,http1.1是客戶端先斷開(有個原則是數據的發送方必定先斷開),具體過程以下:
- 數據發送發確認數據發送完了後,就調用Socket庫的close程序;
- 接下來發送方的協議棧就會生成含斷開控制信息的tcp的數據包(tcp頭部fin:1);並將控制信息同步到套接字中;
- 和第二步相同的方式將含斷開控制信息的數據包發送出去;接收方接收到數據包後,作出確認應答(響應含ack的包);
- 同時接收方將接收到的控制信息同步到套接字;根據套接字控制信息也會調用close程序;以相同的方式發出含斷開控制信息的包;
- 發送方接收到包後會將其控制信息同步到本身的套接字同時確認應答(響應含ack的包);
- 等待一段時間刪除套接字;
5、IP與以太網在包收發過程當中的做用。
第二部講了IP模塊會在tcp包的頭部加上,mac頭部和IP頭部;IP頭部是爲了包在轉發設備中轉發肯定目的地,轉發設備常見的有集線器,交換機(交換式集線器),路由器;經過IP模塊構建包的IP頭實際是查本機的路由表,肯定包的發送端的IP接收端的IP網關IP(網關能夠抽象成接口看待,這裏的網關是指最近可進行轉發路由器的IP)注意IP通常是運營商賦予的可變的通常存在網卡內存中;mac頭部由三部分構成,‘接收方mac,發送方mac,以太類型(包使用的協議類型);因爲發送方mac是網卡驅動程序從網卡rom中複製出來的,所以是固定的,接收方mac能夠根據arp協議來得到’
arp協議是經過廣播的形式將包經過以太網傳輸到局域網的全部終端;來獲取全部終端的mac信息,因爲包自己是帶有最近的轉發設備的IP信息(網關),所以就能肯定須要的是哪一個設備的mac;在根據以太網協議根據包的mac頭部將包傳給了最近的轉發設備;(注意IP協議只肯定包的目的地和下一個轉發路由的地址;實際轉發是經過以太網協議也就是mac實現的)。
6、數據包轉換成電/光信息發送
咱們知道,信號傳輸須要藉助,網線,電纜,或光纖;說明IP包是數字信號是沒法直接傳輸的,須要先轉換成電/光信號才能傳播;這須要藉助網卡實現,網卡結構以下:
![](http://static.javashuo.com/static/loading.gif)
由圖可知IP模塊將數據包傳給網卡後,網卡將數據包存放在網卡的緩存區,後面操做以下:
- 經過網卡的mac模塊對IP數據包進行處理;在數據包前面加上報頭和起始楨分界符,在包最後加上fcs錯誤效驗;
- 報頭是一段1010比特序列用來確認包的讀取時機;起始楨分界符是用來肯定數據包的起始位置;fcs錯誤效驗經過發送方計算出的fcs和接收方計算出的fcs比較來確認包在傳輸過程種頭是否有變化;
- 數據信號即01的比特信號,在電路中傳輸經過高低電壓來表示;爲了能完整表示包的信息經過引入高低起伏的時鐘信號來一塊兒構建,mac模塊結合時鐘信號將數據包轉換爲電信號;
- mac模塊將數據轉換成通用的電信號,在經過PHY(MAU)將信號轉換成在特定介質中傳輸的格式,在經過信號收發模塊將信號發送出去;
- 補充;因爲電信號在介質中傳輸是極快的,所以咱們常說的帶寬,傳輸速率通常是指在PHY模塊上轉換的速率。
- 接收到的電信號轉爲數據包的過程就正好相反,在網卡接收到電信號經過PHY轉換成通用電信號給mac模塊;mac模塊將電信號轉換成數字信號,mac模塊先檢查fcs確認數據無誤後;在查看報頭,如確認數據包是發給本身的就將數據包在轉發給協議棧。
- IP模塊收到網卡發過來的包會先檢查接收方IP確認包是不是發給他的,若是不是就經過icmp消息報錯;若是是的就將包傳給tcp協議;tcp協議在根據包的頭部信息找到接收方的端口;根據端口找到關聯的套接字,讀出包頭部的控制信息並將信息同步到套接字,根據套接字的控制信息執行下一步操做,將數據傳給應用程序的接收緩存區。
7、UDP協議如何進行包的收發操做
UDP和TCP很相似都是用來傳輸數據包的;突出的特色是沒有TCP的應答機制,發送數據包時;接收端接收到包後不會應答不會通知發送方它收到了這個包,所以他不適合傳輸較長鬚要經過多個包傳輸的數據;不過由於沒有應答機制,他的反應更快;通常用做dns查詢域名解析時,音視頻因爲對數據傳輸速度有要求也經常使用udp協議。