日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux sock结构体,struct socket结构体详解

發布時間:2025/3/20 linux 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux sock结构体,struct socket结构体详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在內核中為什么要有struct socket結構體呢?

struct socket結構體的作用是什么?

下面這個圖,我覺得可以回答以上兩個問題。?

由這個圖可知,內核中的進程可以通過使用struct socket結構體來訪問linux內核中的網絡系統中的傳輸層、網絡層、數據鏈路層。也可以說struct socket是內核中的進程與內核中的網路系統的橋梁。

struct?socket

{

socket_state??state;?//?socket?state

short???type?;?//?socket?type

unsigned?long??flags;?//?socket?flags

struct?fasync_struct??*fasync_list;

wait_queue_head_t?wait;

struct?file?*file;

struct?sock?*sock;??//?socket在網絡層的表示;

const?struct?proto_ops?*ops;

}

struct?socket結構體的類型

enum?sock_type

{

SOCK_STREAM?=?1,?//?用于與TCP層中的tcp協議數據的struct?socket

SOCK_DGRAM??=?2,?//用于與TCP層中的udp協議數據的struct?socket

SOCK_RAW????=?3,?//?raw?struct?socket

SOCK_RDM????=?4,?//可靠傳輸消息的struct?socket

SOCK_SEQPACKET?=?5,//?sequential?packet?socket

SOCK_DCCP???=?6,

SOCK_PACKET?=?10,?//從dev?level中獲取數據包的socket

};

struct?socket?中的flags字段取值:

#define?SOCK_ASYNC_NOSPACE??0

#define?SOCK_ASYNC_WAITDATA?1

#define?SOCK_NOSPACE????????2

#define?SOCK_PASSCRED???????3

#define?SOCK_PASSSEC????????4

我們知道在TCP層中使用兩個協議:tcp協議和udp協議。而在將TCP層中的數據往下傳輸時,要使用網絡層的協議,而網絡層的協議很多,不同的網絡使用不同的網絡層協議。我們常用的因特網中,網絡層使用的是IPV4和IPV6協議。

所以在內核中的進程在使用struct socket提取內核網絡系統中的數據時,不光要指明struct socket的類型(用于說明是提取TCP層中tcp協議負載的數據,還是udp層負載的數據),還要指明網絡層的協議類型(網絡層的協議用于負載TCP層中的數據)。

linux內核中的網絡系統中的網絡層的協議,在linux中被稱為address family(地址簇,通常以AF_XXX表示)或protocol family(協議簇,通常以PF_XXX表示)。

1.創建一個struct socket結構體:

int sock_create(int family, int type, int protocol,

struct socket **res);

int sock_create_kern(int family, int type, int protocol,

struct socket **res);

EXPROT_SYMBOL(sock_create);

EXPROT_SYMBOL(sock_create_kern);

family : 指定協議簇的類型,其值為:PF_XXX或 AF_XXX

type?? :指定要創建的struct socket結構體的類型;

protocol : 一般為0;

res??? : 中存放創建的struct socket結構體的地址;int?sock_create(int?family,?int?type,?int?protocol,?struct?socket?**res)

{

return?__sock_create(current->nsproxy->net_ns,?family,?type,?protocol,?res,?0);

}

int?sock_create_kern(int?family,?int?type,?int?protocol,?struct?socket?**res)

{

return?__sock_create(?&init_net,?family,?type,?protocot,?res,?1?);

}

如果在內核中創建struct?socket時,推薦使用sock_create_kern()函數;

//?網絡協議簇結構體

struct?net_proto_family

{

int?family?;?//?協議簇

int?(*create)(struct?net?*net,?struct?socket?*sock,??int?protocol);

struct?module??*owner;

};

內核中的所有的網絡協議的響應的網絡協議簇結構體都存放在?net_families[]指針數組中;

static?struct?net_proto_family?*net_families[NPROTO];

static?int?__sock_create(struct?net?*net,?int?family,?int?type,?int?protocol,

struct?socket?**res,?int?kern?)

{

struct?socket?*sock;

struct?net_proto_family?*pf;

sock?=?sock_alloc();//分配一個struct?socket?結構體

sock->type?=?type;

pf?=?rcu_dereference(net_families[family]);?//獲取相應的網絡協議簇結構體的地址;

pf->create(net,?sock,?protocol);?//?對struct?socket結構體做相應的處理;

*res?=?sock;?//?res中保存創建的struct?socket結構體的地址;

return?0;

}

struct?socket_alloc

{

struct?socket?socket?;

struct?inode?vfs_node?;

}

static?inline?struct?socket?*SOCKET_I(struct?inode?*inode)

{

return?&contain_of(inode,?struct?socket_alloc,?vfs->node)->socket;

}

static?struct?socket?*sock_alloc(void)

{

struct?inode?*inode;

struct?socket?*sock;

inode?=?new_inode(sock_mnt->mnt_sb);//分配一個新的struct?inode節點

sock?=?SOCKET_I(inode);

inode->i_mode?=?S_IFSOCK?|?S_IRWXUGO;//設置inode節點的權限

inode->i_uid?=?current_fsuid();?//?設置節點的UID

inode->i_gid?=?current_fsgid();?//設置節點的GID

return?sock;

}

有以上的代碼可知:linux內核在使用sock_create()、sock_create_kern()

進行struct socket結構體的創建時,其本質是分配了一個struct socket_alloc

結構體,而這個struct socket_alloc結構體中包含了struct socket 和struct

inode(struct inode結構體,是linux內核用來刻畫一個存放在內存中的文件的,通過將struct inode 和 struct socket綁定在一起形成struct socket_alloc結構體,來表示內核中的網絡文件)。然后對分配的struct socket結構體進行初始化,來定義內核中的網絡文件的類型(family, type, protocol).

在linux網絡系統中還有兩個非常重要的套接字地址結構體:

struct sockaddr_in

struct sockaddr;typedef?unsigned?short?sa_family_t;

//?Internet?Address

struct?in_addr{

__b32?s_addr;

}

//struct?describing?an?Internet?socket?address

//sockaddr_in?中存放端口號、網路層中的協議類型(ipv4,ipv6)等,網絡層的IP地址;

struct?sockaddr_in

{

sa_family_t?sin_family?;?//?Address?family?AF_XXX

__be16??????sin_port???;?//?端口號

struct?in_addr?sin_addr?;?//?Internet?Address

/*Pad?to?size?of??'struct?sockaddr'*/

...........

};

//套接字地址結構體。

struct?sockaddr

{

sa_family_t?sa_family;?//?存放網絡層所使用的協議類型(AF_XXX?或?PF_XXX);

char?sa_data[14];???//?里面存放端口號、網絡層地址等信息;

}

從本質上來說,struct sockaddr與struct sockaddr_in是相同的。

但在,實際的使用過程中,struct sockaddr_in是 Internet環境下的套接字地址形式,而struct sockaddr是通過的套接字地址個形式。在linux內核中struct sockaddr使用的更多,目的是使linux內核代碼更為通用。

struct sockaddr_in 可以與 struct sockaddr 進行自由的轉換。

2.將創建的套接字(struct socket)與套接字地址結構體(struct sockaddr or struct sockaddr_in)進行綁定:

int kernel_bind(struct socket *sock, struct sockaddr *addr,

int addrlen)

EXPROT_SYMBOL(kernel_bind);

sock : 為通過sock_create()或sock_create_kern()創建的套接字;

addr : 為套接字地址結構體;

addrlen:為套接字地址結構體的大小;

3.將一個套接字(struct socket)設置為監聽狀態:

int kernel_listen(struct socket *sock, int backlog);

backlog :一般情況下設置為0;

EXPORT_SYMBOL(kernel_listen);

4.當把一個套接字設置為監聽狀態以后,使用這個套接字去監聽其它的套接字;

int kernel_accept(struct socket *sock, struct socket **new_sock,

int flags);

EXPORT_SYMBOL(kernel_accept);

sock : listening socket 處于監聽狀態的套接字;

new_sock : 被監聽的套接字;

flags: struct socket中的flags字段的取值;

5.把一個套接字連接到另一個套接字地址結構體上:

int kernel_connect(struc socket *sock, struct sockaddr *addr,

int addrlen, int flags);

EXPORT_SYMBOL(kernel_connect);

sock : struct socket;

addr : 為另一個新的套接字地址結構體;

addrlen : 套接字地址結構體的大小;

flags :file-related flags associated with socket

6.把一個應用層中的數據發送給另一個設備中的進程:

int kernel_sendmsg(struct socket *sock, struct msghdr *msg,

struct kvec *vec, size_t num, size_t size)

EXPORT_SYMBOL(kernel_sendmsg);

sock : 為當前進程中的struct socket套接字;

msg? : 用于接收來自應用層的數據包;

kvec : 中存放將要發送出去的數據;

num? : 見代碼;

size : 為將要發送的數據的長度;

struct?iovec

{

void?__user?*iov_base;

__kernel_size_t?iov_len;

}

struct?msghdr

{

//用于存放目的進程所使用的套接字地址

void?*msg_name;??//?用于存放目的進程的struct?sockaddr_in

int???msg_namelen;?//?目的進程的sizeof(struct?sockaddr_in)

//用于來自應用層的數據

struct?iovec?*msg_iov?;//?指向一個struct?iovec的數組,數組中的每個成員表示一個數據塊

__kernel_size_t??msg_iovlen?;?//數據塊數,即struct?iovec數組的大小

//用于存放一些控制信息

void?*msg_control?;

__kernel_size_t?msg_controllen;?//控制信息的長度;

//

int?msg_flags;

}

struct?kvec

{

void?*iov_base;?//用于存放來自應用層的數據;

size_t?iov_len;?//來自應用層的數據的長度;

}

struct msghdr中的flags字段的取值為:

int kernel_sendmsg(struct socket *sock, struct msghdr *msg,

struct kvec *vec, size_t num, size_t size)函數的實現為:

有kernel_sendmsg()的實現代碼可知,struct kvec中的數據部分最終還是要放到struct msghdr之中去的。

kernel_sendmsg()的用法:

也可以使用下面這個函數來實現相同的功能:

int sock_sendmsg(struct socket *sock, struct msghdr *msg,

size_t size);

EXPORT_SYMBOL(sock_sendmsg);

7.接受來自另一個網絡進程中的數據:

int kernel_recvmsg(struct socket *sock, struct msghdr *msg,

struct kvec *vec, size_t num, size_t size, int flags)

EXPORT_SYMBOL(kernel_recvmsg);

sock : 為接受進程的套接字;

msg? : 用于存放接受到的數據;

vec? : 用于指向本地進程中的緩存區;

num? : 為數據塊的塊數;

size : 緩存區的大小;

flags: struct msghdr中的flags字段中的取值范圍;

int kernel_recvmsg()的實現:

kernel_recvmsg()的用法:

8.關閉一個套接字:

void sock_release(struct socket *sock);

用于關閉一個套接字,并且如果一個它struct socket綁定到了一個struct

inode節點上的話,相應的struct inode也會被釋放。

以上這些函數位于linux源代碼包中的/net/socket.c之中。

總結

以上是生活随笔為你收集整理的linux sock结构体,struct socket结构体详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 东方av在线免费观看 | 性大片潘金莲裸体 | 在线一级| 韩国中文三级hd字幕 | 天堂在线观看视频 | 日本在线一级片 | 精品国产一区二区三区日日嗨 | 18禁免费无码无遮挡不卡网站 | 亚洲综合av一区二区三区 | 舔花蒂| 免费黄色av网址 | 男人天堂视频在线 | 国产做爰xxxⅹ高潮视频12p | 国产综合第一页 | 日本少妇激情视频 | 精品国产乱码久久久久久蜜臀网站 | 久久国产伊人 | 天堂一区二区三区四区 | 一级黄色大片在线观看 | www.97ai.com | wwwxxxx国产 | 国产午夜福利精品 | 国产精品www在线观看 | 欧美亚洲另类小说 | 成年网站在线观看 | 玖玖999| 美女大黄网站 | 欧美成人精品一区 | 免费av地址 | 久久久男人的天堂 | 欧美色图视频在线 | 成人春色影视 | 视频一区二区不卡 | 中文字幕在线观看欧美 | 国产精品色在线 | 顶级尤物极品女神福利视频 | 又粗又大又硬毛片免费看 | 日本一区二区高清免费 | 成人国产精品免费观看视频 | 三级福利| 欧美成人一区二区三区片免费 | 日韩一区二区在线观看视频 | xxxxwww一片 | 中文字幕第100页 | 色呦呦一区 | 日本一区二区在线视频 | 免费毛片网 | 午夜网站在线 | 亚洲字幕av一区二区三区四区 | 亚洲av综合色区无码一区 | 狠狠看 | 91免费网站 | 欧美成人吸奶水做爰 | www成人免费 | 免费不卡av | 日韩av电影网站 | 日本熟伦人妇xxxx | 欧美视频日韩视频 | 视频三区在线 | 97国产在线播放 | 亚洲爱情岛论坛永久 | 国产色婷婷一区二区三区竹菊影视 | 极品销魂美女少妇尤物 | 国产精品爽爽爽 | 激情五月激情综合 | 人妻丰满熟妇aⅴ无码 | 日韩精品一区二区三区视频在线观看 | 五月天免费网站 | 越南a级片 | 97超碰人人模人人人爽人人爱 | 72pao成人国产永久免费视频 | 国产美女免费网站 | 我的丝袜美腿尤物麻麻 | 6—12呦国产精品 | 暖暖av在线 | 奇米影视欧美 | 美女三级网站 | 69视频一区二区三区 | 精品国产99一区二区乱码综合 | av片网 | 欧美日韩视频无码一区二区三 | 女女同性女同一区二区三区九色 | 无码aⅴ精品一区二区三区浪潮 | 天天看片天天射 | 久久综合久色欧美综合狠狠 | 中文字幕一区二区三区手机版 | 国内久久久久 | av手机免费看 | 在线一区二区三区四区五区 | 亚洲依依 | 国产a视频 | 亚洲第一伊人 | 国产91网 | 欧美一区二区三区视频在线 | 午夜黄色一级片 | 日本极品丰满ⅹxxxhd | 欧美精品一区二区三区在线 | 亚洲中文字幕一区二区 | 午夜精品久久久久久久99热浪潮 |