日韩在线免费播放-日韩在线免费av-日韩在线免费-日韩在线毛片-国产高清不卡视频-国产高清不卡

當(dāng)前位置:首頁(yè) > 嵌入式培訓(xùn) > 嵌入式學(xué)習(xí) > 講師博文 > 使用unix域套接字在進(jìn)程之間傳遞文件描述符

使用unix域套接字在進(jìn)程之間傳遞文件描述符 時(shí)間:2018-09-20      來(lái)源:未知

在多進(jìn)程的程序中經(jīng)常需要在不同的進(jìn)程之間傳遞文件描述符,但是不同的進(jìn)程之間文件描述代表的是不同的對(duì)象。那么如何在不同的進(jìn)程中使用相同的文件描述符,而且代表的是相同的對(duì)象呢?

在linux中可以使用unix的域套接字方法來(lái)實(shí)現(xiàn)在不同的進(jìn)程之間傳遞文件描述符, 需要使用socketpair函數(shù)創(chuàng)建一個(gè)套接字管道,該管道是雙向的,每一端都是可讀可寫(xiě)的。

socketpair的 函數(shù)原型:

int socketpair(int domain, int type, int protocol, int sv[2]);

參數(shù):

Domain: 通信類(lèi)型比如AF_UNIX

type:套接字類(lèi)型比如 SOCK_STREAM、 SOCK_DGRAM

protol:只能為0

sv: 包含兩個(gè)元素的數(shù)組名

函數(shù)執(zhí)行完成之后會(huì)得到sv[0]和sv[1]兩個(gè)套接字描述符。在不同的進(jìn)程之間進(jìn)行通信時(shí)可以使用如下的方法:

每個(gè)進(jìn)程關(guān)閉一個(gè)描述符,然后使用一個(gè)描述符通信。那么有了管道后,如何傳遞文件描述符呢?那就得需要使用sendmsg、recvmsg函數(shù)。

sendmsg函數(shù)用來(lái)給一個(gè)特性的套接字描述符發(fā)送消息。

recvmsg 函數(shù)用來(lái)從一個(gè)特定的套接字中讀取消息。

函數(shù)原型如下:

ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);

ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);

這兩個(gè)函數(shù)的使用關(guān)鍵是struct msghder和 struct cmsghdr?兩個(gè)結(jié)構(gòu)體的使用。

首先, stuct msghdr結(jié)構(gòu)體是用來(lái)發(fā)送和接收消息的結(jié)構(gòu)體,成員如下:struct msghdr {

void *msg_name; //套接字的地址

socklen_t msg_namelen;//套接字地址長(zhǎng)度

struct iovec *msg_iov;//消息結(jié)構(gòu)體的地址

size_t msg_iovlen;//msg_iov結(jié)構(gòu)體的個(gè)數(shù)

void *msg_control;//消息控制緩沖區(qū)

size_t msg_controllen;//消息控制緩沖區(qū)的長(zhǎng)度

int msg_flags;//接收消息時(shí)的標(biāo)志位

};

stcut cmsghdr結(jié)構(gòu)體成員如下:

struct cmsghdr

{

cmsg_len // 附屬數(shù)據(jù)的字節(jié)計(jì)數(shù),這包含結(jié)構(gòu)頭的尺寸。這個(gè)值是由CMSG_LEN()宏計(jì)算的。

cmsg_level // 這個(gè)值表明了原始的協(xié)議級(jí)別(例如,SOL_SOCKET)。

cmsg_type // 這個(gè)值表明了控制信息類(lèi)型(例如,SCM_RIGHTS)。

}

示例代碼如下:

1)接收描述符代碼

int my_recv();

int main(int argc, const char *argv[])

{

int fd;

char buf[32] = {0};

if ((fd = my_recv()) < 0)

{

printf("fail to my_recv\n");

return -1;

}

read(fd, buf, sizeof(buf));

puts(buf);

close(fd);

return 0;

}

int my_recv()

{

int sockfd[2];

int status = -1;

pid_t pid;

char itoa_fd[10] = {0};

if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd) < 0)

{

perror("fail to socketpair");

return -1;

}

pid = fork();

if (pid < 0)

{

perror("Fail to fork");

return -1;

}

else if (pid == 0)

{

close(sockfd[0]);

sprintf(itoa_fd, "%d", sockfd[1]);

if (execl("./sendmsg", "sendmsg", itoa_fd, NULL) < 0)

{

perror("fail to execl");

exit(-1);

}

}

else

{

close(sockfd[1]);

waitpid(pid, &status, 0);

if (WEXITSTATUS(status) != 0)

{

close(sockfd[0]);

printf("sendmsg fail to exit\n");

return -1;

}

struct msghdr msg;

struct cmsghdr *cmsg;

struct iovec iv;

char buf[CMSG_SPACE(sizeof(int))] = {0};

char recv_buf[32] = {0};

msg.msg_control = buf;

msg.msg_controllen = sizeof(buf);

//用來(lái)接收sendmsg發(fā)送的消息

iv.iov_base = recv_buf;

iv.iov_len = sizeof(recv_buf);

msg.msg_iov = &iv;

msg.msg_iovlen = 1;

msg.msg_name = NULL;

msg.msg_namelen = 0;

if (recvmsg(sockfd[0], &msg, 0) < 0)

{

perror("fail to recvmsg");

return -1;

}

if ((cmsg = CMSG_FIRSTHDR(&msg)) != NULL &&cmsg->cmsg_len == CMSG_LEN(sizeof(int)))

{

close(sockfd[0]);

return *(int *)CMSG_DATA(cmsg);

}

close(sockfd[0]);

return -1;

}

}

2)發(fā)送描述符代碼

int my_send(int sockfd, int file);

int main(int argc, const char *argv[])

{

int fd;

if ((fd = open("file", O_RDONLY)) < 0)

{

perror("fail to open the file");

return -1;

}

if (my_send(atoi(argv[1]), fd) < 0)

{

puts("fail to my_send");

close(fd);

return -1;

}

return 0;

}

int my_send(int sockfd, int file)

{

struct msghdr msg;

struct cmsghdr *cmsg;

struct iovec iv;

char buf[CMSG_SPACE(sizeof(int))] = {0};

char send_buf[32] = "helloworld";

bzero(&msg, sizeof(msg));

msg.msg_control = buf;

msg.msg_controllen = sizeof(buf);

//必須要添加消息這一部分,否則sendmsg無(wú)法發(fā)送

iv.iov_base = send_buf;

iv.iov_len = sizeof(send_buf);

msg.msg_iov = &iv;

msg.msg_iovlen = 1;

msg.msg_name = NULL;

msg.msg_namelen = 0;

cmsg = CMSG_FIRSTHDR(&msg);

cmsg->cmsg_len = CMSG_LEN(sizeof(int));

cmsg->cmsg_level = SOL_SOCKET;

cmsg->cmsg_type = SCM_RIGHTS;

*(int*)CMSG_DATA(cmsg) = file;

return sendmsg(sockfd, &msg, 0);

}

上一篇:ViewPager介紹和使用說(shuō)明

下一篇:如何寫(xiě)文檔

熱點(diǎn)文章推薦
華清學(xué)員就業(yè)榜單
高薪學(xué)員經(jīng)驗(yàn)分享
熱點(diǎn)新聞推薦
前臺(tái)專(zhuān)線(xiàn):010-82525158 企業(yè)培訓(xùn)洽談專(zhuān)線(xiàn):010-82525379 院校合作洽談專(zhuān)線(xiàn):010-82525379 Copyright © 2004-2022 北京華清遠(yuǎn)見(jiàn)科技集團(tuán)有限公司 版權(quán)所有 ,京ICP備16055225號(hào)-5,京公海網(wǎng)安備11010802025203號(hào)

回到頂部

主站蜘蛛池模板: 孽子 电影| 比基尼美女跳舞视频| 上瘾演员表| 影片 - theav| 追捕渣滓洞刽子手电视剧全集在线观看| 燃烧的岁月| 《我的美女老板》电视剧| 悠悠寸草心第一部| 追捕演员表名单| 苏捷斯卡战役 电影| 电影在线观看免费完整高清网站 | 伊利亚伍德| 成都影院大全| a面b面| 阿尔法变频器说明书| av电影网| 意大利人在俄罗斯的奇遇| 蔡宜达的老婆吴佩柔照片| 膨腹爱好者撑肚子视频| 肮脏性感的人| 滑胎最凶的食物孕早期| 电影《kiskisan》在线播放| 电影《一秒钟》完整版| 电影《48天》免费观看全集| 亚洲电影在线观看| 欧美成熟| 我的神我要敬拜你歌谱| dj歌曲串烧中文大全| 女用春情药什么好| 琅琊榜 豆瓣| 美女的咪咪| 永远少年电影免费播放 | 局外人电影| 二胡独奏我的祖国| 生活秀| 贾林| 山上的小屋 残雪原文| av网址大全| 李采潭全部作品百度| 基础设施建设产业市场| 陈建斌电影|