当前位置: 首页 > news >正文

0725,进程间传递文件描述符,socketpair + sendmsg/recvmsg

我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了

上课喵:

pipe匿名管道的问题

#include <func.h>int main()
{int fds[2];pipe(fds);pid_t pid=fork();if(pid>0){ //fatherclose(fds[0]);//close readint fd=open("file2.txt",O_RDONLY);printf("father: fds[1]:%d\n",fds[1]);write(fds[1],&fd,sizeof(fd));wait(NULL);close(fd);}else{   //sonclose(fds[1]);//close erint chilfd=-1;read(fds[0],&chilfd,sizeof(chilfd));  //read baba pipeprintf("chilefd %d.fds [0]:%d\n",chilfd,fds[0]);char buff[100]={0};read(chilfd,buff,sizeof(buff));printf("buff  %s.\n",buff);}return 0;
}

writev

#include <func.h>
#include <sys/uio.h>int main()
{char buff[]="love";char buff2[]="xixi";int fd=open("file2.txt",O_RDWR|O_CREAT,0664);if(fd==-1){};struct iovec iov[2];iov[0].iov_base=buff;iov[0].iov_len=strlen(buff);iov[1].iov_base=buff2;iov[1].iov_len=strlen(buff2);int ret=writev(fd,iov,2);printf("ret :%d \n",ret);close(fd);return 0;
}

readv

#include <func.h>
#include <sys/uio.h>int main()
{char buff[6]={0};char buff2[6]={0};int fd=open("file2.txt",O_RDWR);if(fd==-1){};struct iovec iov[2];iov[0].iov_base=buff;/* iov[0].iov_len=strlen(buff); */iov[0].iov_len=sizeof(buff);iov[1].iov_base=buff2;iov[1].iov_len=sizeof(buff2);int ret=readv(fd,iov,2);printf("ret :%d \n",ret);printf("buff:%s \n",buff);printf("buff2:%s \n",buff2);close(fd);return 0;
}

结构体struct msghdr的发送和接收实现

真是酣畅淋漓的CP

代码改好了!!
./wr33: sendmsg: Bad file descriptor
嘿嘿~~~因为没有文件所以打开失败了!!!聪明小辉

#include <func.h>
#include <sys/uio.h>int sendFd(int pipefd,int fd){//buid 2 groupchar buff[6]="hellp";struct iovec iov;memset(&iov,0,sizeof(iov));iov.iov_base=buff;iov.iov_len=sizeof(buff);//build 3 groupint len=CMSG_LEN(sizeof(fd));struct cmsghdr* cmsg=(struct cmsghdr*)calloc(1,len);cmsg->cmsg_len=len;cmsg->cmsg_level=SOL_SOCKET;cmsg->cmsg_type=SCM_RIGHTS;int * p=(int*)CMSG_DATA(cmsg);*p=fd;// buid msghdrstruct msghdr msg;memset(&msg,0,sizeof(msg));msg.msg_iov=&iov;msg.msg_iovlen=1;msg.msg_control=cmsg;//传递文件描述msg.msg_controllen=len;int ret=sendmsg(pipefd,&msg,0);printf("sendmsg ret: %d\n",ret);if(ret==-1){error(1,errno,"sendmsg");}free(cmsg);return 0;
}int recvFd(int pipefd,int *pfd){//buid 2 groupchar buff[6]={0};struct iovec iov;memset(&iov,0,sizeof(iov));iov.iov_base=buff;iov.iov_len=sizeof(buff);//3 groupint len=CMSG_LEN(sizeof(int));struct cmsghdr* cmsg=(struct cmsghdr*)calloc(1,len);cmsg->cmsg_len=len;cmsg->cmsg_level=SOL_SOCKET;cmsg->cmsg_type=SCM_RIGHTS;struct msghdr msg;memset(&msg,0,sizeof(msg));msg.msg_iov=&iov;msg.msg_iovlen=1;msg.msg_control=cmsg;//传递文件描述符msg.msg_controllen=len;int ret =recvmsg(pipefd,&msg,0);if(ret==-1){error(1,errno,"recvmsg");}int* p=(int*)CMSG_DATA(cmsg);printf("buff: %s\n",buff);*pfd=*p;//传给外籍的指针(读取文件描述符的值)return 0;
}int main()
{int fds[2];socketpair(AF_LOCAL,SOCK_STREAM,0,fds);pid_t pid=fork();if(pid>0){ //fatherclose(fds[0]);//close readint fd=open("file1.txt",O_RDONLY);printf("father fd:%d\n",fd);/* write(fds[1],&fd,sizeof(fd)); */sendFd(fds[1],fd);wait(NULL);close(fd);}else{   //sonclose(fds[1]);//close erint chilfd=-1;/* read(fds[0],&chilfd,sizeof(chilfd));  //read baba pipe */recvFd(fds[0],&chilfd);printf("chilefd %d.fds [0]:%d\n",chilfd,fds[0]);char buff[100]={0};read(chilfd,buff,sizeof(buff));printf("buff  %s.\n",buff);}return 0;
}

 进程池框架的搭建

作业:

01:参考我们上课的代码: 让子进程A打开一个文件, 把这个文件描述符信息发给父进程B, 让父进程B在这个文件上能写一个字符串. 

好像没什么用??????

#include <func.h>
#include <sys/uio.h>int sendFd(int pipefd,int fd){//buid 2 groupchar buff[6]={0};struct iovec iov;memset(&iov,0,sizeof(iov));iov.iov_base=buff;iov.iov_len=sizeof(buff);//build 3 groupint len=CMSG_LEN(sizeof(fd));struct cmsghdr* cmsg=(struct cmsghdr*)calloc(1,len);cmsg->cmsg_len=len;cmsg->cmsg_level=SOL_SOCKET;cmsg->cmsg_type=SCM_RIGHTS;int * p=(int*)CMSG_DATA(cmsg);*p=fd;// buid msghdrstruct msghdr msg;memset(&msg,0,sizeof(msg));msg.msg_iov=&iov;msg.msg_iovlen=1;msg.msg_control=cmsg;//传递文件描述msg.msg_controllen=len;int ret=sendmsg(pipefd,&msg,0);if(ret==-1){error(1,errno,"sendmsg");}free(cmsg);return 0;
}int recvFd(int pipefd,int *pfd){//buid 2 groupchar buff[6]={0};struct iovec iov;memset(&iov,0,sizeof(iov));iov.iov_base=buff;iov.iov_len=sizeof(buff);//3 groupint len=CMSG_LEN(sizeof(int));struct cmsghdr* cmsg=(struct cmsghdr*)calloc(1,len);cmsg->cmsg_len=len;cmsg->cmsg_level=SOL_SOCKET;cmsg->cmsg_type=SCM_RIGHTS;struct msghdr msg;memset(&msg,0,sizeof(msg));msg.msg_iov=&iov;msg.msg_iovlen=1;msg.msg_control=cmsg;//传递文件描述符msg.msg_controllen=len;int ret =recvmsg(pipefd,&msg,0);if(ret==-1){error(1,errno,"recvmsg");}int* p=(int*)CMSG_DATA(cmsg);*pfd=*p;//传给外籍的指针(读取文件描述符的值)return 0;
}int main()
{int fd[2];int err=socketpair(AF_LOCAL,SOCK_STREAM,0,fd);if(err==-1){error(1,errno,"sockpair");}int pid=fork();switch (pid){case -1:error(1,errno,"fork");break;case 0:{close(fd[0]);printf("child process:%d\n",getpid());int pfd;recvFd(fd[1],&pfd);char buff[]="我恨你我恨你我恨你!!!!!\n";write(pfd,buff,sizeof(buff));close(pfd);break;}default:{close(fd[1]);int filefd=open("file2.txt",O_RDWR);if(filefd==-1){error(1,errno,"open");}sendFd(fd[0],filefd);break;}      }return 0;
}

所以那狗东西要怎么打印出来可恶!!!! 

02:仿照我们上课写的进程池, 自己手写(不要直接复制)一个进程池代码。

抄抄抄:

02:使用select编写聊天室程序:客户端和服务端使用tcp通信;服务端可以处理新客户端的连接和转发消息;客户端可以连入服务端并发送消息。

哥们发现少一个右括号直接傻眼了喵
xiaohuichen@xiaohuichen-virtual-machine:~/001/724$ cat douqusi.c
#include <func.h>
#define IP1  "192.168.235.128"
#define PORT1 8080int main()
{struct sockaddr_in addr;addr.sin_family=AF_INET;addr.sin_port=htons(PORT1);addr.sin_addr.s_addr=inet_addr(IP1);int lifd=socket(AF_INET,SOCK_STREAM,0);bind(lifd,(struct sockaddr *)&addr,sizeof(struct sockaddr));listen(lifd,100);int ac_fd[1000];int ac_num=0;char buf[256];char buf_sent[256];fd_set readfds;FD_ZERO(&readfds);int fd_max;FD_SET(lifd,&readfds);fd_max=lifd;fd_set old_fds=readfds;printf("listenning\n");while(1){readfds=old_fds;select (fd_max+1,&readfds,NULL,NULL,NULL);if(FD_ISSET(lifd,&readfds)){ac_fd[ac_num]=accept(lifd,NULL,NULL);FD_SET(ac_fd[ac_num],&old_fds);if(ac_fd[ac_num]>fd_max){fd_max=ac_fd[ac_num];}ac_num++;printf("welcome user%d \n",ac_fd[ac_num-1]);}for(int i=0;i<ac_num;i++){if(FD_ISSET(ac_fd[i],&readfds)){int a=recv(ac_fd[i],buf,256,0);if(a==0){close(ac_fd[i]);}}sprintf(buf_sent,"user%d:%s",ac_fd[i],buf);for(int j=0;j<ac_num;j++){send(ac_fd[j],buf_sent,strlen(buf_sent)+1,0);}}}return 0;
}

HTTP:(咳咳,是我不知道怎么跑然后连了一个客户端喵)

#include <func.h>
#define IP1  "192.168.235.128"
#define PORT1 8080struct sockaddr* addr_create(const char* ip,int  port ){struct sockaddr_in* addr=(struct sockaddr_in*)malloc(sizeof(struct sockaddr_in));memset(addr,0,sizeof(*addr));addr->sin_family=AF_INET;addr->sin_port=htons(port);addr->sin_addr.s_addr=inet_addr(ip);return (struct sockaddr*)addr;
}int main()
{int sofd=socket(AF_INET,SOCK_STREAM,0);if(sofd==-1){error(1,errno,"socket");}int on=1;int ret=setsockopt(sofd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));if(ret==-1){error(1,errno,"setsoclopt");}struct sockaddr* addr=addr_create(IP1,PORT1);ret=bind(sofd,addr,sizeof(*addr));if(ret==-1){error(1,errno,"bind");}ret=listen(sofd,1);while(1){int peerfd=accept(sofd,NULL,NULL);char buff[4096]={0};ret=recv(peerfd,buff,sizeof(buff),0);printf("\nrecv: %d.bytes \n",ret);printf("----%s\n",buff);char response[4096]={0};const char* start_line="HTTP/1.1 200 ok\r\n";const char* headers="Server:MyHttpServer1.0\r\n""Connection:keep-aliave\r\n""Conntent-Type:text/html\r\n""Content-Length:";const char* empty_line="\r\n";const char* body="<html><head>This is a test</head><body>hello,client</body></html>";sprintf(response,"%s%s%ld\r\n%s%s",start_line,headers,strlen(body),empty_line,body);send(peerfd,response,strlen(response),0);}close(sofd);return 0;
}

http://www.lryc.cn/news/408996.html

相关文章:

  • 放大电路总结
  • 深度学习1-简介
  • Java基础语法 (基础介绍 二)
  • SAPUI5基础知识18 - 自定义CSS和主题色
  • Postman中API测试的艺术:测试用例复用的高级技巧
  • Flutter Geocoding插件使用指南:简化地理编码与逆地理编码
  • “手撕”全网最细的JDBC教程(安装导入使用)
  • C++指针选择题带答案
  • 力扣 二分查找
  • ADMAS-Simulink联合仿真输入设置
  • 【NOI】C++程序设计入门三
  • Three.js投射光线实现三维物体交互
  • SSRF学习笔记
  • Python——Pandas(第三讲)
  • 性能测试中qps 一直上不去的原因
  • 学习笔记14:CNAME 记录值、TTL (Time to Live)、Redis 的 Pool 对象池、钩子函数、依赖注入
  • springboot集成mybatis时,dao层的mapper类需要添加@Repository注解吗?
  • 一文总结代理:代理模式、代理服务器
  • 探索 Kubernetes 持久化存储之 Longhorn 初窥门径
  • 全国区块链职业技能大赛样题第9套智能合约+数据库表设计
  • 常见OVS网桥及其链接接口详解
  • 创建最最最纯净 Windows 11/10 系统镜像!| 全网独一份
  • 带你学会Git必会操作
  • clickhouse处理readonly报错
  • 使用git命令行的方式,将本地项目上传到远程仓库
  • jetbrains InterlliJ IDEA 2024.1 版本最新特性一览: Java 相关内容
  • 百日筑基第三十四天-JAVA中的强/软/弱/虚引用
  • C语言100基础拔高题(3)
  • AV1技术学习:Constrained Directional Enhancement Filter
  • C++的STL简介(一)