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