五月天青色头像情侣网名,国产亚洲av片在线观看18女人,黑人巨茎大战俄罗斯美女,扒下她的小内裤打屁股

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

Linux內(nèi)核角度分析服務(wù)器Listen細節(jié)

2022-07-28 15:59 作者:補給站Linux內(nèi)核  | 我要投稿

Listen功能簡述

編寫服務(wù)器程序時,在Linux中需要調(diào)用Listen系統(tǒng)調(diào)用,如下所示,Listen系統(tǒng)調(diào)用的主要功能就是根據(jù)傳入的backlog參數(shù)創(chuàng)建連接隊列,并將套接字的狀態(tài)遷移至LISTEN狀態(tài),最后將監(jiān)聽sock注冊到TCP全局的監(jiān)聽套接字哈希表。

Listen系統(tǒng)調(diào)用-函數(shù)執(zhí)行流程

系統(tǒng)調(diào)用調(diào)用的函數(shù)執(zhí)行如下所示:

其中sockfd_lookup_light函數(shù)根據(jù)fd描述符得到struct socket結(jié)構(gòu)體,并找到當(dāng)前系統(tǒng)設(shè)定的最大可監(jiān)聽連接數(shù)somaxconn ,PROC文件系統(tǒng)中somaxconn默認為128,意味著單個套接口隊列的長度,可最大監(jiān)聽128個連接 ,如下所示:

somaxconn與Listen系統(tǒng)調(diào)用傳入的參數(shù)backlog進行比較,若當(dāng)前傳入的參數(shù)backlog大于somaxconn則使用somaxconn,即backlog最大值不能超過somaxconn。該系統(tǒng)調(diào)用核心是執(zhí)行:sock->ops->listen(sock,backlog) ;也就是說找到服務(wù)器的socket后,通過它的協(xié)議操作表結(jié)構(gòu)struct proto_ops執(zhí)行其listen鉤子函數(shù),proto_ops協(xié)議操作表結(jié)構(gòu)的掛入是在socket創(chuàng)建過程根據(jù)協(xié)議類型進行設(shè)置的,TCP實際掛入的是inet_stream_ops操作表結(jié)構(gòu),listen在inet_stream_ops表中的賦值如下所示:


【文章福利】小編推薦自己的Linux內(nèi)核技術(shù)交流群:【891587639】整理了一些個人覺得比較好的學(xué)習(xí)書籍、視頻資料共享在群文件里面,有需要的可以自行添加哦?。。。ê曨l教程、電子書、實戰(zhàn)項目及代碼)? ? ? ?


故sock->ops->listen針對于TCP而言,繼續(xù)調(diào)用inet_listen函數(shù):

inet_listen函數(shù)首先是對套接字類型、狀態(tài)進行檢查,類型必須是流式套接字且狀態(tài)必須是close或者listen狀態(tài):

inet_listen函數(shù)核心的繼續(xù)調(diào)用inet_csk_start_listen函數(shù):

inet_csk_listen_start函數(shù)通過reqsk_queue_alloc創(chuàng)建連接隊列,隊列結(jié)構(gòu)體如下,隊列的最大長度是sk_max_ack_backlog,也就是用戶傳入的backlog參數(shù)值,隊列的長度計數(shù)是sk_ack_backlog。

其中request_sock結(jié)構(gòu)體是請求隊列的節(jié)點如下所示,*dl_next將所有的accept請求串起來。

struct request_sock_queue和struct request_sock的關(guān)系如下:


inet_csk_listen_start調(diào)用的分配并初始化連接隊列的函數(shù)reqsk_queue_alloc如下所示,其中可以看到queue->rskq_accept_head初始化為NULL

inet_csk_listen_start函數(shù)中另一個核心內(nèi)容就是調(diào)用哈希函數(shù):

sk->sk_prot->hash(sk)將監(jiān)聽sock注冊到TCP全局的監(jiān)聽套接字哈希表,對于TCP對應(yīng)的協(xié)議棧,hash函數(shù)是inet_hash:

繼續(xù)調(diào)用__inet_hash:

關(guān)于:

struct inet_hashinfo *hashinfo = sk->sk_prot->h.hashinfo;

通過圖解,如下所示:


最終得到struct inet_hashinfo:

內(nèi)核將監(jiān)聽隊列分為32個哈希桶bucket:listening_hash[INET_LHTABLE_SIZE],保存處于監(jiān)聽狀態(tài)的TCP套接口哈希鏈表,每個哈希桶由獨立的保護鎖和鏈表,此結(jié)構(gòu)通過減小鎖的粒度,增加并行處理的可能,每個哈希桶如下所示:

哈希桶的選擇由函數(shù)inet_sk_listen_hashfn的返回值決定

inet_sk_listen_hash函數(shù)使用數(shù)據(jù)包的目的端口號(本地監(jiān)聽端口號)計算的hash值為索引得到具體的哈希桶,如下所示:

內(nèi)核為處于LISTEN狀態(tài)的socket分配了大小為32的哈希桶,監(jiān)聽的端口號經(jīng)過哈希算法運算打散到這些哈希桶中(如果開啟了IPV6,并且啟用了端口重用,將此套接口添加在監(jiān)聽套接口桶的鏈表末尾;否則,添加到鏈表頭部,如下代碼所示)

如下圖所示,哈希鏈表的組織方式:


當(dāng)收到客戶端的 SYN 握手報文以后,會根據(jù)目標(biāo)端口號的哈希值計算出哈希沖突鏈表,然后遍歷這條哈希鏈表得到對應(yīng)的socket。


Linux內(nèi)核角度分析服務(wù)器Listen細節(jié)的評論 (共 條)

分享到微博請遵守國家法律
彰化县| 黔江区| 昭平县| 搜索| 阿克陶县| 蕉岭县| 耿马| 德保县| 图木舒克市| 亚东县| 资兴市| 六枝特区| 龙井市| 奉节县| 霍州市| 闸北区| 化德县| 喀什市| 遂溪县| 莲花县| 剑阁县| 宁国市| 库伦旗| 云龙县| 鄄城县| 故城县| 晴隆县| 南溪县| 枞阳县| 府谷县| 安溪县| 横山县| 曲麻莱县| 长沙市| 姜堰市| 蒲江县| 东阿县| 肥乡县| 贵阳市| 万安县| 如东县|