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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

内核中用于数据接收的结构体struct msghdr

發(fā)布時(shí)間:2025/3/15 编程问答 13 豆豆
生活随笔 收集整理的這篇文章主要介紹了 内核中用于数据接收的结构体struct msghdr 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

我們從一個(gè)實(shí)際的數(shù)據(jù)包發(fā)送的例子入手,來(lái)看看其發(fā)送的具體流程,以及過(guò)程中涉及到的相關(guān)數(shù)據(jù)結(jié)構(gòu)。在我們的虛擬機(jī)上發(fā)送icmp回顯請(qǐng)求包,ping另一臺(tái)主機(jī)172.16.48.1。我們使用系統(tǒng)調(diào)用sendto發(fā)送這個(gè)icmp包。

???? ssize_t sendto(int s, const void *buf, size_t len, int flags,

??????????????????????? const struct sockaddr *to, socklen_t tolen);

??? s就是socket的fd。buf是待發(fā)送的icmp數(shù)據(jù)包,len是buf的長(zhǎng)度。flags可以是下列標(biāo)志位的位或:

??? MSG_DONTROUTE

??? 在發(fā)送分組時(shí),不使用網(wǎng)關(guān),只有直接連接在本網(wǎng)絡(luò)中的主機(jī)才能接收到數(shù)據(jù)。這個(gè)標(biāo)志通常僅用于診斷和路由程序。可路由的協(xié)議族才能使用這個(gè)標(biāo)志;packet sockets不可以使用。

??? MSG_DONTWAIT

??? 使用非阻塞操作。

??? MSG_NOSIGNAL

??? 當(dāng)流式套接字的另一端中斷連接時(shí)不發(fā)送SIGPIPE信號(hào),但仍然返回EPIPE錯(cuò)誤。

??? MSG_CONFIRM (僅用于Linux 2.3以上版本)

??? 通知鏈路層發(fā)生了轉(zhuǎn)發(fā)過(guò)程:得到了另一端的成功應(yīng)答。如果鏈路層沒(méi)有收到通知,它將按照常規(guī)探測(cè)網(wǎng)絡(luò)上的相鄰主機(jī)(比如通過(guò)免費(fèi)arp)。只能用于 SOCK_DGRAM和SOCK_RAW類型的套接字,且僅對(duì)IPv4和IPv6有效。

??? 除此之外,還有MSG_MORE,MSG_OOB,MSG_EOR。

??? to是這個(gè)數(shù)據(jù)包發(fā)送的目地端地址,tolen是to的長(zhǎng)度。

??? 系統(tǒng)調(diào)用sendto最終調(diào)用內(nèi)核函數(shù):

??????? asmlinkage long sys_sendto(int fd, void __user * buff, size_t len,

??????????????????????? unsigned flags, struct sockaddr __user *addr, int addr_len)

??? sys_sendto構(gòu)建一個(gè)結(jié)構(gòu)體struct msghdr,用于接收來(lái)自應(yīng)用層的數(shù)據(jù)包,下面是結(jié)構(gòu)體struct msghdr的定義:

??????? struct msghdr {

??????????? void??????????? *msg_name;

??????????? int???????????? msg_namelen;

??????????? struct iovec??? *msg_iov;

??????????? __kernel_size_t msg_iovlen;

??????????? void??????????? *msg_control;

??????????? __kernel_size_t msg_controllen;

??????????? unsigned??????? msg_flags;

??????? };

??? 這個(gè)結(jié)構(gòu)體的內(nèi)容可以分為四組。

??? 第一組是msg_name和msg_namelen,記錄這個(gè)消息的名字,其實(shí)就是數(shù)據(jù)包的目的地址。msg_name是指向一個(gè)結(jié)構(gòu)體struct sockaddr的指針。長(zhǎng)度為16:

??????? struct sockaddr{

??????????? sa_family_t sa_family;

??????????? char??????? sa_addr[14];

??????? }

所以,msg_namelen的長(zhǎng)度為16。需要注意的是,結(jié)構(gòu)體struct sockaddr只在進(jìn)行參數(shù)傳遞時(shí)使用,無(wú)論是在用戶態(tài)還是在內(nèi)核態(tài),我們都把其強(qiáng)制轉(zhuǎn)化為結(jié)構(gòu)體struct sockaddr_in:

??????? strcut sockaddr_in{

??????????? sa_family_t???????? sin_family;

??????????? unsigned short int? sin_port;

??????????? struct in_addr????? sin_addr;

??????????? unsigned char?????? __pad[__SOCK_SIZE__ - sizeof(short int) -

??????????????????????????????? sizeof(unsigned short int) - sizeof(struct in_addr)];

??????? };

??????? struct in_addr{

??????????? __u32 s_addr;

??????? }

__SOCK_SIZE__的值為16,所以,struct sockaddr中真正有用的數(shù)據(jù)只有8bytes。在我們的ping例子中,傳入到內(nèi)核的msghdr結(jié)構(gòu)中:

??? msg.msg_name = { sa_family_t = MY_AF_INET, sin_port = 0, sin_addr.s_addr = 172.16.48.1 }

??? msg_msg_namelen = 16。

請(qǐng)求回顯icmp包沒(méi)有目的端地址的端口號(hào)。

??? 第二組是msg_iov和msg_iovlen,記錄這個(gè)消息的內(nèi)容。msg_iov是一個(gè)指向結(jié)構(gòu)體struct iovec的指針,實(shí)際上,確切地說(shuō),應(yīng)該是一個(gè)結(jié)構(gòu)體strcut iovec的數(shù)組。下面是該結(jié)構(gòu)體的定義:

??? struct iovec{

??????? void __user???? *iov_base;

??????? __kernel_size_t iov_len;

??? };

??? iov_base指向數(shù)據(jù)包緩沖區(qū),即參數(shù)buff,iov_len是buff的長(zhǎng)度。msghdr中允許一次傳遞多個(gè)buff,以數(shù)組的形式組織在 msg_iov中,msg_iovlen就記錄數(shù)組的長(zhǎng)度(即有多少個(gè)buff)。在我們的ping程序的實(shí)例中:

??? msg.msg_iov = { struct iovec = { iov_base = { icmp頭+填充字符'E' }, iov_len = 40 } }

??? msg.msg_len = 1

??? 第三組是msg_control和msg_controllen,它們可被用于發(fā)送任何的控制信息,在我們的例子中,沒(méi)有控制信息要發(fā)送。暫時(shí)略過(guò)。

??? 第四組是msg_flags。其值即為傳入的參數(shù)flags。raw協(xié)議不支持MSG_OOB標(biāo)志,即帶外數(shù)據(jù)。

總結(jié)

以上是生活随笔為你收集整理的内核中用于数据接收的结构体struct msghdr的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。