1. 概述
TCP/IP協(xié)議棧可以實現(xiàn)不同型號脂倦、不同操作系統(tǒng)的計算機之間的通信番宁,它并不是某個具體的協(xié)議,而是一組協(xié)議赖阻。我們都知道OSI七層模型中有物理層蝶押、數(shù)據(jù)鏈路層、網(wǎng)絡層火欧、傳輸層棋电、會話層、表示層布隔、應用層共七層,每一層都對應多個相關的協(xié)議稼虎。同樣衅檀,TCP/IP網(wǎng)絡協(xié)議也進行了層次的劃分,分為四層霎俩,分別規(guī)定了每層的作用以及它們的協(xié)議哀军。
網(wǎng)絡接口層:通常包括操作系統(tǒng)中的設備驅動程序和計算機中對應的網(wǎng)卡,它們一起處理與電纜的物理接口細節(jié)打却。
網(wǎng)絡層:有時也稱作網(wǎng)際層或互聯(lián)網(wǎng)層杉适,處理分組在網(wǎng)絡中的活動,例如分組的選路柳击。在
T C P / I P協(xié)議族中猿推,網(wǎng)絡層協(xié)議包括I P協(xié)議(網(wǎng)際協(xié)議),ICMP協(xié)議(I n t e r n e t互聯(lián)網(wǎng)控制報文協(xié)議),以及IGMP協(xié)議(I n t e r n e t組管理協(xié)議)蹬叭。
運輸層:主要為兩臺主機上的應用程序提供端到端的通信藕咏。在TCP/IP協(xié)議族中,有兩個互不相同的傳輸協(xié)議:TCP(傳輸控制協(xié)議)和UDP(用戶數(shù)據(jù)報協(xié)議)秽五。TCP為兩臺主機提供高可靠性的數(shù)據(jù)通信孽查。它所做的工作包括把應用程序交給它的數(shù)據(jù)分成合適的小塊交給下面的網(wǎng)絡層,確認接收到的分組坦喘,設置發(fā)送最后確認分組的超時時鐘等盲再。由于運輸層提供了高可靠性的端到端的通信,因此應用層可以忽略所有這些細節(jié)瓣铣。而另一方面答朋,UDP則為應用層提供一種非常簡單的服務。它只是把稱作數(shù)據(jù)報的分組從一臺主機發(fā)送到另一臺主機坯沪,但并不保證該數(shù)據(jù)報能到達另一端绿映。任何必需的可靠性必須由應用層來提供。這兩種運輸層協(xié)議分別在不同的應用程序中有不同的用途腐晾,這一點將在后面看到叉弦。
應用層:負責處理特定的應用程序細節(jié)
假設在一個局域網(wǎng)(LAN)如以太網(wǎng)中有兩臺主機,二者都運行FTP協(xié)議,如圖列出了該過程所涉及到的所有協(xié)議藻糖。
這里淹冰,我們列舉了一個FTP客戶程序和另一個FTP服務器程序。大多數(shù)的網(wǎng)絡應用程序都被設計成客戶-服務器模式巨柒。服務器為客戶提供某種服務樱拴,在該圖中就是訪問服務器所在主機上的文件。在遠程登錄應用程序Telnet中洋满,為客戶提供的服務是登錄到服務器主機上晶乔。在同一層上,雙方都有對應的一個或多個協(xié)議進行通信牺勾。例如正罢,某個協(xié)議允許TCP層進行通信,而另一個協(xié)議則允許兩個IP層進行通信驻民。在圖的右邊翻具,我們可以看出應用程序通常是一個用戶進程,而下三層則一般在linux操作系統(tǒng)內核中執(zhí)行回还。頂層與下三層之間還有另一個關鍵的不同之處裆泳。應用層關心的是應用程序的細節(jié),而不是數(shù)據(jù)在網(wǎng)絡中的傳輸活動柠硕。下三層對應用程序一無所知工禾,但它們要處理所有的通信細節(jié)。在圖中列舉了四種不同層次上的協(xié)議。FTP是一種應用層協(xié)議帜篇,?TCP是一種運輸層協(xié)議糙捺,IP是一種網(wǎng)絡層協(xié)議,而以太網(wǎng)協(xié)議則應用于鏈路層上笙隙。TCP/IP協(xié)議族是一組不同的協(xié)議組合在一起構成的協(xié)議族洪灯。盡管通常稱該協(xié)議族為TCP/IP,但TCP和IP只是其中的兩種協(xié)議而已(該協(xié)議族的另一個名字是I n t e r n e t協(xié)議族(Internet Protocol Suite))竟痰。網(wǎng)絡接口層和應用層的目的是很顯然的—前者處理有關通信媒介的細節(jié)(以太網(wǎng)签钩、令牌環(huán)網(wǎng)等),而后者處理某個特定的用戶應用程序(?FT P坏快、Telnet等)铅檩。但是,從表面上看莽鸿,網(wǎng)絡層和運輸層之間的區(qū)別不那么明顯昧旨。
2. 數(shù)據(jù)封裝
數(shù)據(jù)從應用層到物理層要經(jīng)過一系列的加包頭過程,反之祥得,從物理層到應用層要進行拆包兔沃,每經(jīng)過一層就要進行相應的去數(shù)據(jù)包包頭。
3. 數(shù)據(jù)傳輸
數(shù)據(jù)的傳輸使用了一個非常重要的結構體sk_buff级及,該結構體用來實現(xiàn)數(shù)據(jù)在各個層次的數(shù)據(jù)傳輸乒疏。該數(shù)據(jù)結構在linux內核源碼的頭文件中進行的聲明,結構體主要成員變量如下:
struct sk_buff {
struct sk_buff?????? *next;
struct sk_buff?????? *prev;
struct net_device *dev;???????? //數(shù)據(jù)包屬于哪個網(wǎng)卡
unsigned int????? len,????????? //有效數(shù)據(jù)長度
data_len;? ?? //分片數(shù)據(jù)段的長度
__u16???????????? mac_len,?? ?
hdr_len;
sk_buff_data_t?????? tail;
sk_buff_data_t?????? end;????????
unsigned char???? *head,??????? //緩存區(qū)的頭指針
*data; ?????? //有效數(shù)據(jù)頭指針
...
};
sk_buff相關操作函數(shù):
?? /*********************************************************
??? *功能:分配sk_buff結構體
???? *參數(shù):size?:緩存區(qū)大小
???? *?????? ?? priority:分配標志GFP_KERNEL,GFP_ATOMIC...
???? *返回值:成功返回skb指針
*?失敗返回NULL
??? ********************************************************/
?? struct sk_buff *alloc_skb(unsigned int size,gfp_t priority)
?? /**********************************************************
???? *功能:釋放sk_buff
???? *參數(shù):skb:skb指針
???? *返回值:void
???? **********************************************************/
???? void kfree_skb(struct sk_buff *skb)
???? /*tail下移饮焦,有效數(shù)據(jù)區(qū)增大*/
???? unsigned char *skb_put(struct sk_buff *skb, unsigned int len);
???? /*data上移怕吴,有效數(shù)據(jù)區(qū)增大*/
???? unsigned char *skb_push(struct sk_buff *skb, unsigned int len);
???? /*data tail下移,有效數(shù)據(jù)區(qū)不變*/
???? void skb_reserve(struct sk_buff *skb, int len)
-------------------------------------------------------------------------------------------------------------------------------------------
推薦大家一個嵌入式資料分享交流群:707159742 入群有全套學習視頻資料和電子書免費贈送(基礎教程县踢、ARM開發(fā)转绷、QT編程,C語言硼啤、C++語言议经,Linux、數(shù)據(jù)結構丙曙。)
大神爸业、小白聚集地其骄。
進群驗證:簡書
-------------------------------------------------------------------------------------------------------------------------------------------