套接字的秘密—socket與sock

??那么如何把套接字和文件聯(lián)系起來(lái)呢刊头? 答案就是通過(guò)下面這張圖原杂。

image.png

其中task_struct表示一個(gè)進(jìn)程污尉,files_struct中的fd_array[]表示該進(jìn)程打開(kāi)的所有描述符被碗,對(duì)于套接字來(lái)說(shuō)锐朴,與其他類型文件的區(qū)別就是最終f_op指向的是socket_file_ops蔼囊。不過(guò)畏鼓,可以看到,這里的socket_file_ops只有一些通用的操作膳沽,并沒(méi)有sendrecv挑社。特有的操作通過(guò) socketcall() 區(qū)分的巡揍。

socket和sock

??終于到今天的主角了腮敌。實(shí)際上,對(duì)每一個(gè)新創(chuàng)建的套接字斗这,內(nèi)核協(xié)議棧都會(huì)創(chuàng)建struct socketstruct sock兩個(gè)數(shù)據(jù)結(jié)構(gòu)。這兩個(gè)結(jié)構(gòu)就像孿生兄弟钮莲,struct socket面向用戶空間,struct sock面向內(nèi)核空間崔拥。
struct socket簡(jiǎn)化版的結(jié)構(gòu)如下:

struct socket {
    unsigned long flags;
    const struct proto_ops *ops;
    struct file *file;
    struct sock *sk;
    short type;
 };

??其中type表示協(xié)議链瓦,這是在創(chuàng)建套接字的時(shí)候的protocol參數(shù)確定的,

int socket(int domain, int type, int protocol);

??file指針指向上面那張圖中的struct file結(jié)構(gòu)慈俯,通過(guò)它,socket便與文件系統(tǒng)關(guān)聯(lián)了起來(lái)卖子。
??sk指向?qū)\生的兄弟sock結(jié)構(gòu)洋闽。
??socket結(jié)構(gòu)中最重要的要數(shù)ops指針了诫舅,根據(jù)協(xié)議類型宫患,它指向一種特定協(xié)議的實(shí)現(xiàn)撮奏。比如TCP的就是inet_stream_ops; ICMP、UDP協(xié)議對(duì)應(yīng)inet_dgram_ops;RAWIP對(duì)應(yīng)的是inet_sockraw_ops同樣地泽疆,這些也都在創(chuàng)建套接字的時(shí)候就決定了殉疼。
??struct proto_ops的簡(jiǎn)化版本的結(jié)構(gòu)如下

struct proto_ops{ int family;
                  int (*bind)(struct socket *sock, struct sockaddr *myaddr, int sockaddr_len);
                  int (*connect)(struct socket *sock,struct sockaddr *vaddr,int sockaddr_len, int flags);
                  int (*accept)(struct socket *sock, struct socket *newsock, int flags);
                  int (*sendmsg)(struct socket *sock, struct msghdr *m, size_t total_len);
}

其中的接口名字是不是很熟悉瓢娜?是的眠砾,它們和進(jìn)行網(wǎng)絡(luò)編程時(shí)調(diào)用的C庫(kù)中函數(shù)名字是一樣的托酸。以sendmsg為例柒巫,真實(shí)的調(diào)用過(guò)程是這樣

image.png

即當(dāng)用戶調(diào)用sendmsg時(shí),內(nèi)核會(huì)找到描述符fd對(duì)應(yīng)的struct socket結(jié)構(gòu)刨疼,然后調(diào)用sock->ops->sendmsg執(zhí)行特定協(xié)議的發(fā)送揩慕。那么,ops字段什么時(shí)候被賦值呢贱案?
??答案是宝踪,在創(chuàng)建struct sock結(jié)構(gòu)前碍扔。struct sock的簡(jiǎn)化結(jié)構(gòu)如下圖所示

struct sock_common {
      struct proto *skc_prot;
};

struct sock {
      struct sock_common __sk_common;
      struct sk_buff_head sk_receive_queue;
      struct sk_buff_head sk_write_queue;
};

其中最重要的字段就是skc_prot不同,它也是協(xié)議相關(guān)的。作為struct socket結(jié)構(gòu)的孿生兄弟服鹅,struct sock結(jié)構(gòu)也是在用戶創(chuàng)建套接字時(shí)就創(chuàng)建的企软。

image.png

sock_alloc創(chuàng)建了struct socket結(jié)構(gòu)仗哨,隨后厌漂,根據(jù)用戶傳入的family斟珊,查詢數(shù)組net_families,找到對(duì)應(yīng)的函數(shù)指針胜嗓,調(diào)用create函數(shù)钩乍。net_families保存著內(nèi)核啟動(dòng)時(shí)注冊(cè)(通過(guò)sock_register)的 socket protocol handler寥粹,比如以下幾種

static const struct net_proto_family inet_family_ops = { 
      .family = PF_INET, 
      .create = inet_create, 
      .owner = THIS_MODULE, 
}; 
static const struct net_proto_family netlink_family_ops = { 
     .family = PF_NETLINK,
     .create = netlink_create,
     .owner = THIS_MODULE, /* for consistency 8) */ 
};
static const struct net_proto_family packet_family_ops = { 
     .family = PF_PACKET, 
     .create = packet_create,
     .owner = THIS_MODULE,
}; 
static const struct net_proto_family unix_family_ops = { 
      .family = PF_UNIX, 
      .create = unix_create, 
      .owner = THIS_MODULE,
};

image.png

inetsw中注冊(cè)的每種協(xié)議都有opsprot兩個(gè)字段,前者與struct socket結(jié)構(gòu)關(guān)聯(lián)到一起岛杀,后者與struct sock關(guān)聯(lián)到一起类嗤。在inet_create中,struct socketops字段和struct socksk_prot字段被賦值货裹。


本文全部?jī)?nèi)容轉(zhuǎn)載自:套接字的秘密—socket與sock

待整理文章:Linux 網(wǎng)絡(luò)棧剖析

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末弧圆,一起剝皮案震驚了整個(gè)濱河市搔预,隨后出現(xiàn)的幾起案子叶组,更是在濱河造成了極大的恐慌扶叉,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件溢十,死亡現(xiàn)場(chǎng)離奇詭異张弛,居然都是意外死亡吞鸭,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門遮咖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)御吞,“玉大人陶珠,你說(shuō)我怎么就攤上這事享钞。” “怎么了暑脆?”我有些...
    開(kāi)封第一講書人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵饵筑,是天一觀的道長(zhǎng)根资。 經(jīng)常有香客問(wèn)我同窘,道長(zhǎng),這世上最難降的妖魔是什么裤纹? 我笑而不...
    開(kāi)封第一講書人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任鹰椒,我火速辦了婚禮漆际,結(jié)果婚禮上夺饲,老公的妹妹穿的比我還像新娘施符。我一直安慰自己戳吝,他們只是感情好贯涎,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布柬采。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪肩刃。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,708評(píng)論 1 305
  • 那天盈包,我揣著相機(jī)與錄音呢燥,去河邊找鬼寓娩。 笑死,一個(gè)胖子當(dāng)著我的面吹牛寞埠,可吹牛的內(nèi)容都是我干的焊夸。 我是一名探鬼主播,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼揪阶!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起遣钳,我...
    開(kāi)封第一講書人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎姐直,沒(méi)想到半個(gè)月后蒋畜,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡插龄,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年均牢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了徘跪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖坞琴,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情寒亥,我是刑警寧澤浙于,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布羞酗,位于F島的核電站,受9級(jí)特大地震影響胸竞,放射性物質(zhì)發(fā)生泄漏参萄。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一校赤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧马篮,春花似錦、人聲如沸翅阵。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至蜂科,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間崇摄,已是汗流浹背逐抑。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工厕氨, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留汹粤,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像芹壕,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子踢涌,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容