网络协议栈11:Connect函数分解之TCP层
Connect函數(shù)之分解1.
首先,connect函數(shù)從參數(shù)獲得遠(yuǎn)端的IP,把這個(gè)地址賦值給對(duì)應(yīng)的sock結(jié)構(gòu)體的對(duì)應(yīng)變量,并設(shè)置了sock結(jié)構(gòu)體中的一些其他變量后,首先分配(skb_buff+用戶空間)大小內(nèi)存,這兩部分是通過(guò)調(diào)用kmalloc(sizeof(struct skb_buff)+size,priority)來(lái)分配的,分配后兩個(gè)數(shù)據(jù)塊是連續(xù)的地址;分配后的內(nèi)存如下
?
接下來(lái),就是初始化這個(gè)剛剛分配好的skb_buff結(jié)構(gòu)體的一些指針成員,之后,把整個(gè)數(shù)據(jù)空間的首地址返回給一個(gè)skb_buff指針,以后對(duì)skb結(jié)構(gòu)體的操作,就通過(guò)這個(gè)指針來(lái)完成了。接著,把skb_buff跟sock關(guān)聯(lián)起來(lái),即把skb_buff的成員sk設(shè)置為對(duì)應(yīng)的sock,路由指向本地路由,就開始配置通信數(shù)據(jù)了。
?
第一步,把指針指向skb_buff空間的數(shù)據(jù)空間,即skb_buff的成員data所指向的地址(上圖 5)。
第二步(上圖 1),設(shè)置以太網(wǎng)頭部(本地MAC地址6字節(jié)+遠(yuǎn)端MAC地址6字節(jié)+數(shù)據(jù)幀類型2字節(jié)),把本地MAC地址復(fù)制到數(shù)據(jù)空間的開始處,本地的MAC地址,是從本地路由中獲得,而目的MAC地址一般為NULL,如果為NULL,則需要設(shè)置skb_buff成員arp為0,表示遠(yuǎn)端MAC地址(或者下一跳MAC地址)并不知道,需要在發(fā)送數(shù)據(jù)之前使用ARP來(lái)查找,數(shù)據(jù)幀可以選擇:
#define ETH_P_LOOP? 0x0060?????????? /* Ethernet Loopback packet? */
#define ETH_P_ECHO? 0x0200?????????? /* Ethernet Echo packet??????? */
#define ETH_P_PUP???? 0x0400?????????? /* Xerox PUP packet??????????? */
#define ETH_P_IP 0x0800?????????? /* Internet Protocol packet??? */
#define ETH_P_ARP???? 0x0806?????????? /* Address Resolution packet */
#define ETH_P_RARP????? 0x8035????????? /* Reverse Addr Res packet?? */
#define ETH_P_X25???? 0x0805?????????? /* CCITT X.25???????????????????? */
#define ETH_P_ATALK 0x809B????????? /* Appletalk DDP????????? */
#define ETH_P_IPX????? 0x8137?????????? /* IPX over DIX????????????????? */
#define ETH_P_802_3?? 0x0001?????????? /* Dummy type for 802.3 frames? */
#define ETH_P_AX25?? 0x0002?????????? /* Dummy protocol id for AX.25? */
#define ETH_P_ALL???? 0x0003?????????? /* Every packet (be careful!!!) */
#define ETH_P_802_2?? 0x0004?????????? /* 802.2 frames ?????????? */
#define ETH_P_SNAP? 0x0005?????????? /* Internal only???????????? */
?
第三步,指針跳過(guò)以太網(wǎng)首部14字節(jié),指向IP首部(上圖 2),跟著就是數(shù)據(jù)空間初始化IP首部,IP首部的數(shù)據(jù)基本上在sock結(jié)構(gòu)體中都有用,現(xiàn)在只是從sock結(jié)構(gòu)體復(fù)制過(guò)來(lái),初始化完后,在skb_buff中還有一個(gè)專門的指針指向數(shù)據(jù)空間的IP首部的地址的成員ip_hdr,此時(shí)也初始化一下。
?
第四步,指針跳過(guò)IP首部,指向TCP首部(上圖 3),跟著初始化數(shù)據(jù)空間的tcp首部,tcp首部一些是從sock結(jié)構(gòu)體中復(fù)制的,一些是在這里第一次被賦值的,注意tcp首部不包含tcp選項(xiàng)部分,因此,需要把指針跳過(guò)tcp首部后,指向tcp的選項(xiàng)部分,進(jìn)行初始化,才算把tcp初始化完成(把MSS賦值到選項(xiàng)部分)(上圖 4)。
?
到此,我們就把數(shù)據(jù)空間初始化完,我們?cè)陂_始時(shí)分配數(shù)據(jù)空間大小為44+18,現(xiàn)在使用的是14(MAC)+20(TCP)+20(IP)+4(MSS),也就用完了,從這里,我們看到,connect函數(shù)發(fā)送的數(shù)據(jù),都是本地的一些信息,包裝到MAC,TCP,IP等結(jié)構(gòu)體中,目的是告知遠(yuǎn)端本地的一些情況的信息,以后通信時(shí),就按照現(xiàn)在發(fā)送的規(guī)格進(jìn)行了,而真正的數(shù)據(jù)部分是沒有的。
?
最后,就是把數(shù)據(jù)發(fā)送的網(wǎng)絡(luò)層,進(jìn)行排隊(duì)了。
轉(zhuǎn)載于:https://www.cnblogs.com/image-eye/archive/2012/01/11/2319798.html
總結(jié)
以上是生活随笔為你收集整理的网络协议栈11:Connect函数分解之TCP层的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows 7 shortcut i
- 下一篇: T-SQL编程基础-基本语法