linux内核网络接收数据流程图【转】
生活随笔
收集整理的這篇文章主要介紹了
linux内核网络接收数据流程图【转】
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
轉(zhuǎn)自:http://blog.chinaunix.net/uid-23069658-id-3141409.html
4.3 數(shù)據(jù)接收流程圖
各層主要函數(shù)以及位置功能說明:?
1)sock_read:初始化msghdr{}的結(jié)構(gòu)類型變量msg,并且將需要接收的數(shù)據(jù)存放的地址傳給msg.msg_iov->iov_base.????? net/socket.c 2)sock_recvmsg: 調(diào)用函數(shù)指針sock->ops->recvmsg()完成在INET Socket層的數(shù)據(jù)接收過程.其中sock->ops被初始化為inet_stream_ops,其成員recvmsg對應(yīng)的函數(shù)實現(xiàn)為inet_recvmsg()函數(shù). net/socket.c 3)sys_recv()/sys_recvfrom():分別對應(yīng)著面向連接和面向無連接的協(xié)議兩種情況. net/socket.c 4)inet_recvmsg:調(diào)用sk->prot->recvmsg函數(shù)完成數(shù)據(jù)接收,這個函數(shù)對于tcp協(xié)議便是tcp_recvmsg net/ipv4/af_net.c 5)tcp_recvmsg:從網(wǎng)絡(luò)協(xié)議棧接收數(shù)據(jù)的動作,自上而下的觸發(fā)動作一直到這個函數(shù)為止,出現(xiàn)了一次等待的過程.函數(shù)tcp_recvmsg可能會被動地等待在sk的接收數(shù)據(jù)隊列上,也就是說,系統(tǒng)中肯定有其他地方會去修改這個隊列使得tcp_recvmsg可以進(jìn)行下去.入口參數(shù)sk是這個網(wǎng)絡(luò)連接對應(yīng)的sock{}指針,msg用于存放接收到的數(shù)據(jù).接收數(shù)據(jù)的時候會去遍歷接收隊列中的數(shù)據(jù),找到序列號合適的. 但讀取隊列為空時tcp_recvmsg就會調(diào)用tcp_v4_do_rcv使用backlog隊列填充接收隊列. 6)tcp_v4_rcv:tcp_v4_rcv被ip_local_deliver函數(shù)調(diào)用,是從IP層協(xié)議向INET Socket層提交的"數(shù)據(jù)到"請求,入口參數(shù)skb存放接收到的數(shù)據(jù),len是接收的數(shù)據(jù)的長度,這個函數(shù)首先移動skb->data指針,讓它指向tcp頭,然后更新tcp層的一些數(shù)據(jù)統(tǒng)計,然后進(jìn)行tcp的一些值的校驗.再從INET Socket層中已經(jīng)建立的sock{}結(jié)構(gòu)變量中查找正在等待當(dāng)前到達(dá)數(shù)據(jù)的哪一項.可能這個sock{}結(jié)構(gòu)已經(jīng)建立,或者還處于監(jiān)聽端口、等待數(shù)據(jù)連接的狀態(tài)。返回的sock結(jié)構(gòu)指針存放在sk中。然后根據(jù)其他進(jìn)程對sk的操作情況,將skb發(fā)送到合適的位置.調(diào)用如下:?
TCP包接收器(tcp_v4_rcv)將TCP包投遞到目的套接字進(jìn)行接收處理. 當(dāng)套接字正被用戶鎖定,TCP包將暫時排入該套接字的后備隊列(sk_add_backlog).這時如果某一用戶線程企圖鎖定該套接字(lock_sock),該線程被排入套接字的后備處理等待隊列(sk->lock.wq).當(dāng)用戶釋放上鎖的套接字時(release_sock,在tcp_recvmsg中調(diào)用),后備隊列中的TCP包被立即注入TCP包處理器(tcp_v4_do_rcv)進(jìn)行處理,然后喚醒等待隊列中最先的一個用戶來獲得其鎖定權(quán). 如果套接字未被上鎖,當(dāng)用戶正在讀取該套接字時, TCP包將被排入套接字的預(yù)備隊列(tcp_prequeue),將其傳遞到該用戶線程上下文中進(jìn)行處理.如果添加到sk->prequeue不成功,便可以添加到 sk->receive_queue隊列中(用戶線程可以登記到預(yù)備隊列,當(dāng)預(yù)備隊列中出現(xiàn)第一個包時就喚醒等待線程.)?? /net/tcp_ipv4.c?
7)ip_rcv、ip_rcv_finish:從以太網(wǎng)接收數(shù)據(jù),放到skb里,作ip層的一些數(shù)據(jù)及選項檢查,調(diào)用ip_route_input()做路由處理,判斷是進(jìn)行ip轉(zhuǎn)發(fā)還是將數(shù)據(jù)傳遞到高一層的協(xié)議.調(diào)用skb->dst->input函數(shù)指針,這個指針的實現(xiàn)可能有多種情況,如果路由得到的結(jié)果說明這個數(shù)據(jù)包應(yīng)該轉(zhuǎn)發(fā)到其他主機(jī),這里的input便是ip_forward;如果數(shù)據(jù)包是給本機(jī)的,那么input指針初始化為ip_local_deliver函數(shù)./net/ipv4/ip_input.c?
8)ip_local_deliver、ip_local_deliver_finish:入口參數(shù)skb存放需要傳送到上層協(xié)議的數(shù)據(jù),從ip頭中獲取是否已經(jīng)分拆的信息,如果已經(jīng)分拆,則調(diào)用函數(shù)ip_defrag將數(shù)據(jù)包重組。然后通過調(diào)用ip_prot->handler指針調(diào)用tcp_v4_rcv(tcp)。ip_prot是inet_protocol結(jié)構(gòu)指針,是用來ip層登記協(xié)議的,比如由udp,tcp,icmp等協(xié)議。 /net/ipv4/ip_input. 【作者】張昺華 【出處】http://www.cnblogs.com/sky-heaven/ 【博客園】 http://www.cnblogs.com/sky-heaven/ 【新浪博客】 http://blog.sina.com.cn/u/2049150530 【知乎】 http://www.zhihu.com/people/zhang-bing-hua 【我的作品---旋轉(zhuǎn)倒立擺】 http://v.youku.com/v_show/id_XODM5NDAzNjQw.html?spm=a2hzp.8253869.0.0&from=y1.7-2 【我的作品---自平衡自動循跡車】 http://v.youku.com/v_show/id_XODM5MzYyNTIw.html?spm=a2hzp.8253869.0.0&from=y1.7-2 【新浪微博】 張昺華--sky 【twitter】 @sky2030_ 【facebook】 張昺華 zhangbinghua 本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責(zé)任的權(quán)利.總結(jié)
以上是生活随笔為你收集整理的linux内核网络接收数据流程图【转】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Redis启动多端口,运行多实例(转)
- 下一篇: Android Studio的git功能