利用socketpair创建类全双工管道进行父子进程通信
fork的使用
struct msghdr hdr;赋值操作需要熟练掌握
//实现父进程传输文件对象给子进程
int sendfd(int Wpipefd,int fdtosend)
{
struct msghdr hdr;
bzero(&hdr,sizeof(hdr));//一定要记得初始化hdr
//进行正文信息的打包 正文部分一定要写
char buf1[]="hello";
char buf2[]="world";
struct iovec iov[2];
iov[0].iov_base=buf1;
iov[0].iov_len=5;
iov[1].iov_base=buf2;
iov[1].iov_len=5;
hdr.msg_iov=iov;
hdr.msg_iovlen=2;
//进行控制信息的打包 这次我们的data是要进行传输的文件描述符
struct cmsghdr *pcmsghdr;//可变长结构体一定要通过结构体指针指向calloc分配的堆区
pcmsghdr = (struct cmsghdr *)calloc(1,CMSG_LEN(sizeof(int)));
pcmsghdr->cmsg_len=CMSG_LEN(sizeof(int));//fdsize=4B;
pcmsghdr->cmsg_level=SOL_SOCKET;
pcmsghdr->cmsg_type=SCM_RIGHTS;//类型说明了要传递的是一个文件对象
*(int *)CMSG_DATA(pcmsghdr)=fdtosend;//先获取data区域的首地址然后强转成int* 再接引用然后赋值
hdr.msg_control=pcmsghdr;
hdr.msg_controllen=CMSG_LEN(sizeof(int));
//两部分打包好后 剩下的就是通过socketpair搞出来的管道 传递hdr大结构体
int ret=sendmsg(Wpipefd,&hdr,0);
ERROR_CHECK(ret,-1,"sendmsg");
return 0;
}
int recvfd(int Rpipefd,int *pfdtosend)
{
struct msghdr hdr;
bzero(&hdr,sizeof(hdr));//一定要记得初始化hdr
////进行正文信息的打包 正文部分一定要写
char buf1[6]={0};
char buf2[6]={0};
struct iovec iov[2];
iov[0].iov_base=buf1;
iov[0].iov_len=5;
iov[1].iov_base=buf2;
iov[1].iov_len=5;
hdr.msg_iov=iov;
hdr.msg_iovlen=2;
//进行控制信息的打包 这次我们的data是要进行传输的文件描述符
struct cmsghdr*pcmsghdr=(struct cmsghdr*)calloc(1,CMSG_LEN(sizeof(int)));
pcmsghdr->cmsg_len=CMSG_LEN(sizeof(int));
pcmsghdr->cmsg_level=SOL_SOCKET;
pcmsghdr->cmsg_type=SCM_RIGHTS;
hdr.msg_control=pcmsghdr;
hdr.msg_controllen=CMSG_LEN(sizeof(int));
int ret=recvmsg(Rpipefd,&hdr,0);
//把从管道接收到的hdr结构体中的信息打印出来
printf("%s\n",(char *)hdr.msg_iov[0].iov_base);
printf("%s\n",(char *)hdr.msg_iov[1].iov_base);
printf("recvfdFunc:filefd=%d\n",*(int*)CMSG_DATA(pcmsghdr));
*pfdtosend=*(int*)CMSG_DATA(pcmsghdr);
return 0;
}
int main()
{
int pipefd[2]={0};
int ret;
ret=socketpair(AF_LOCAL,SOCK_STREAM,0,pipefd);
ERROR_CHECK(ret,-1,"socketpair");
//pipefd[0] for reading and pipefd[1] for writing
if(0==fork())//return value is 0 standing for child process
{
//usleep(1000);
puts("I am child process");
close(pipefd[1]);
int filefd;
recvfd(pipefd[0],&filefd);
ret=write(filefd,"Fanbing Wu",11);
ERROR_CHECK(ret,-1,"ChildP:write");
printf("child:filefd=%d\n",filefd);
exit(0);
}
else//main process
{
int filefd=open("file",O_RDWR|O_CREAT,0666);
ret=write(filefd,"Yujie Lai",10);
ERROR_CHECK(ret,-1,"MainP:write");
sendfd(pipefd[1],filefd);
printf("Main:filefd=%d\n",filefd);
wait(NULL);
}
}
本文介绍了如何通过本地套接字和socketpair方法建立父子进程间的全双工通信。重点讲解了在C语言环境下,如何使用fork创建子进程,并利用struct msghdr结构体进行消息传递,实现子进程共享父进程的文件对象。

7370

被折叠的 条评论
为什么被折叠?



