1. 概述
TCP/IP協議棧可以實現不同型號、不同操作系統的計算機之間的通信,它并不是某個具體的協議,而是一組協議。我們都知道OSI七層模型中有物理層、數據鏈路層、網絡層、傳輸層、會話層、表示層、應用層共七層,每一層都對應多個相關的協議。同樣,TCP/IP網絡協議也進行了層次的劃分,分為四層,分別規定了每層的作用以及它們的協議。
網絡接口層:通常包括操作系統中的設備驅動程序和計算機中對應的網卡,它們一起處理與電纜的物理接口細節。
網絡層:有時也稱作網際層或互聯網層,處理分組在網絡中的活動,例如分組的選路。在
T C P / I P協議族中,網絡層協議包括I P協議(網際協議),ICMP協議(I n t e r n e t互聯網控制報文協議),以及IGMP協議(I n t e r n e t組管理協議)。
運輸層:主要為兩臺主機上的應用程序提供端到端的通信。在TCP/IP協議族中,有兩個互不相同的傳輸協議:TCP(傳輸控制協議)和UDP(用戶數據報協議)。TCP為兩臺主機提供高可靠性的數據通信。它所做的工作包括把應用程序交給它的數據分成合適的小塊交給下面的網絡層,確認接收到的分組,設置發送后確認分組的超時時鐘等。由于運輸層提供了高可靠性的端到端的通信,因此應用層可以忽略所有這些細節。而另一方面,UDP則為應用層提供一種非常簡單的服務。它只是把稱作數據報的分組從一臺主機發送到另一臺主機,但并不保證該數據報能到達另一端。任何必需的可靠性必須由應用層來提供。這兩種運輸層協議分別在不同的應用程序中有不同的用途,這一點將在后面看到。
應用層:負責處理特定的應用程序細節
假設在一個局域網(LAN)如以太網中有兩臺主機,二者都運行FTP協議,如圖列出了該過程所涉及到的所有協議。
這里,我們列舉了一個FTP客戶程序和另一個FTP服務器程序。大多數的網絡應用程序都被設計成客戶-服務器模式。服務器為客戶提供某種服務,在該圖中就是訪問服務器所在主機上的文件。在遠程登錄應用程序Telnet中,為客戶提供的服務是登錄到服務器主機上。在同一層上,雙方都有對應的一個或多個協議進行通信。例如,某個協議允許TCP層進行通信,而另一個協議則允許兩個IP層進行通信。在圖的右邊,我們可以看出應用程序通常是一個用戶進程,而下三層則一般在linux操作系統內核中執行。頂層與下三層之間還有另一個關鍵的不同之處。應用層關心的是應用程序的細節,而不是數據在網絡中的傳輸活動。下三層對應用程序一無所知,但它們要處理所有的通信細節。在圖中列舉了四種不同層次上的協議。FTP是一種應用層協議, TCP是一種運輸層協議,IP是一種網絡層協議,而以太網協議則應用于鏈路層上。TCP/IP協議族是一組不同的協議組合在一起構成的協議族。盡管通常稱該協議族為TCP/IP,但TCP和IP只是其中的兩種協議而已(該協議族的另一個名字是I n t e r n e t協議族(Internet Protocol Suite))。網絡接口層和應用層的目的是很顯然的—前者處理有關通信媒介的細節(以太網、令牌環網等),而后者處理某個特定的用戶應用程序( FT P、Telnet等)。但是,從表面上看,網絡層和運輸層之間的區別不那么明顯。
2.數據封裝
數據從應用層到物理層要經過一系列的加包頭過程,反之,從物理層到應用層要進行拆包,每經過一層就要進行相應的去數據包包頭。
3. 數據傳輸
數據的傳輸使用了一個非常重要的結構體sk_buff,該結構體用來實現數據在各個層次的數據傳輸。該數據結構在linux內核源碼的
struct sk_buff {
struct sk_buff *next;
struct sk_buff *prev;
struct net_device *dev; //數據包屬于哪個網卡
unsigned int len, //有效數據長度
data_len; //分片數據段的長度
__u16 mac_len,
hdr_len;
sk_buff_data_t tail;
sk_buff_data_t end;
unsigned char *head, //緩存區的頭指針
*data; //有效數據頭指針
...
};
sk_buff相關操作函數:
/*********************************************************
*功能:分配sk_buff結構體
*參數:size :緩存區大小
* priority:分配標志GFP_KERNEL,GFP_ATOMIC...
*返回值:成功返回skb指針
* 失敗返回NULL
********************************************************/
struct sk_buff *alloc_skb(unsigned int size,gfp_t priority)
/**********************************************************
*功能:釋放sk_buff
*參數:skb:skb指針
*返回值:void
**********************************************************/
void kfree_skb(struct sk_buff *skb)
/*tail下移,有效數據區增大*/
unsigned char *skb_put(struct sk_buff *skb, unsigned int len);
/*data上移,有效數據區增大*/
unsigned char *skb_push(struct sk_buff *skb, unsigned int len);
/*data tail下移,有效數據區不變*/
void skb_reserve(struct sk_buff *skb, int len)