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

news2024/11/18 12:25:55

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

上课喵:

pipe匿名管道的问题

#include <func.h>

int main()
{
    int fds[2];
    pipe(fds);
    pid_t pid=fork();
    if(pid>0){ //father
        close(fds[0]);//close read
        int 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{   //son
        close(fds[1]);//close er
        int chilfd=-1;
        read(fds[0],&chilfd,sizeof(chilfd));  //read baba pipe
        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;
}

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 group
    char buff[6]="hellp";
    struct iovec iov;
    memset(&iov,0,sizeof(iov));
    iov.iov_base=buff;
    iov.iov_len=sizeof(buff);

    //build 3 group
    int 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 msghdr
    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=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 group
    char buff[6]={0};
    struct iovec iov;
    memset(&iov,0,sizeof(iov));
    iov.iov_base=buff;
    iov.iov_len=sizeof(buff);

    //3 group
    int 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){ //father
        close(fds[0]);//close read
        int 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{   //son
        close(fds[1]);//close er
        int 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 group
    char buff[6]={0};
    struct iovec iov;
    memset(&iov,0,sizeof(iov));
    iov.iov_base=buff;
    iov.iov_len=sizeof(buff);

    //build 3 group
    int 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 msghdr
    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=sendmsg(pipefd,&msg,0);
    if(ret==-1){error(1,errno,"sendmsg");}
    free(cmsg);
    return 0;
}

int recvFd(int pipefd,int *pfd){

    //buid 2 group
    char buff[6]={0};
    struct iovec iov;
    memset(&iov,0,sizeof(iov));
    iov.iov_base=buff;
    iov.iov_len=sizeof(buff);

    //3 group
    int 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 8080

int 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 8080

struct 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.coloradmin.cn/o/1949166.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Jsoup爬虫——自学习梳理

——项目已完结&#xff08;源码在文末&#xff09; 一个较大的项目&#xff0c;通过后台进行网站爬虫&#xff0c;选择的是一个招聘类型的网站&#xff0c;爬取数据后会选择一部分放入到我们的数据库中&#xff0c;前台通过后台返回的Json数据进行展示&#xff1b;大概就是这样…

CSS(五)——CSS Fonts(字体)

CSS 字体 CSS字体属性定义字体&#xff0c;加粗&#xff0c;大小&#xff0c;文字样式。 CSS字型 在CSS中&#xff0c;有两种类型的字体系列名称&#xff1a; 通用字体系列 - 拥有相似外观的字体系统组合&#xff08;如 "Serif" 或 "Monospace"&#x…

mysql特殊字符、生僻字存储设置

mysql utf-8模式下&#xff0c;分为ut8mb3,utf8mb4&#xff0c;mb4是支持特殊字符、emoji表情的&#xff0c;mb3是不支持的。 报错信息&#xff1a; 1### Error updating database. Cause: java.sql.SQLException: Incorrect string value: \xF0\xA8\x92\x82\xE6\x95... fo…

vue3+ts+vite+electron+electron-packager打包成exe文件

目录 1、创建vite项目 2、添加需求文件 3、根据package.json文件安装依赖 4、打包 5、electron命令运行 6、electron-packager打包成exe文件 Build cross-platform desktop apps with JavaScript, HTML, and CSS | Electron 1、创建vite项目 npm create vitelatest 2、添…

hipBLAS示例程序

GPT-4o (OpenAI) 当然&#xff01;以下是一个简单示例&#xff0c;展示了如何使用hipBLAS库进行矩阵-向量乘法 (GEMV) 的操作。该示例包括初始化 hipBLAS 环境&#xff0c;设置矩阵和向量数据并调用hipBLAS API来执行操作。 首先&#xff0c;确保你已经安装了 ROCm&#xff08…

PYTHON学习笔记(八、字符串及的使用)

目录 1、字符串 1.1、字符串的常用操作 1.2、格式化字符串 1.2.1、占位符格式化字符串 1.2.2、f-string格式化字符串 1.2.3、str.format( )格式化字符串 1.3、数据的验证 1.4、正则表达式 1.5.1元字符 1.5.2限定符 1.5.3其他字符 1.5.4re模块 1、字符串 1.1、字符…

如何安全的申请SSL证书

随着数字化时代的快速发展&#xff0c;互联网政务应用已成为政府服务民众、提升治理效能的重要途径。在这个网络日益复杂的时代&#xff0c;政务网站的安全问题显得尤为重要。2024年&#xff0c;国家出台并从2024年7月1日开始实施执行《互联网政务应用安全管理规定》&#xff0…

系统移植(一)u-boot相关命令

文章目录 一、概念&#xff08;一&#xff09;GNU相关命令的扩展(二进制工具集)&#xff08;二&#xff09;1. ld命令&#xff1a;将.o文件链接生成.elf格式文件2. objcopy命令&#xff1a;格式化拷贝命令&#xff0c;将.elf格式文件格式化拷贝生成.bin文件3. objdump命令&…

idea中项目目录,文件显示不全问题

问题&#xff1a;idea中项目目录显示不全问题 解决办法1&#xff1a; 删除目录中的.idea文件 用idea重新打开文件就行了 办法2&#xff1a;手动导入为maven项目 1. 2. 3. 4.选择要导入的项目&#xff0c;导入为maven

vue3前端开发-小兔鲜项目-登录组件的开发表单验证

vue3前端开发-小兔鲜项目-登录组件的开发表单验证&#xff01;现在开始写登录页面的内容。首先这一次完成基础的首页按钮点击跳转&#xff0c;以及初始化一些简单的表单的输入验证。后期还会继续完善内容。 1&#xff1a;首先还是准备好login页面的组件代码内容。 <script …

四、GD32 MCU 常见外设介绍(8)SPI 模块介绍

串行外设接口&#xff08;Serial Peripheral Interface&#xff0c;缩写为 SPI&#xff09; 提供了基于SPI 协议的数据发送和接收功能&#xff0c; 可以工作于主机或从机模式。 SPI 接口支持具有硬件 CRC 计算和校验的全双工和单工模式。 8.1.SPI 基础知识 SPI 物理层 SPI接…

Pytorch使用教学7-张量的广播

PyTorch中的张量具有和NumPy相同的广播特性&#xff0c;允许不同形状的张量之间进行计算。 广播的实质特性&#xff0c;其实是低维向量映射到高维之后&#xff0c;相同位置再进行相加。我们重点要学会的就是低维向量如何向高维向量进行映射。 相同形状的张量计算 虽然我们觉…

自动驾驶(八十八)---------通讯之SOMEIP

1. 什么是SOME/IP 服务导向架构&#xff08;SOA&#xff0c;Service-Oriented Architecture&#xff09;是一种设计软件系统的方法&#xff0c;强调通过可重用的服务来实现系统的松散耦合。每个服务是独立的功能单元&#xff0c;可以被不同的应用程序使用。这些服务通过标准化的…

新版海螺影视主题模板M3.1全解密版本多功能苹果CMSv10后台自适应主题

苹果CMS2022新版海螺影视主题M3.1版本&#xff0c;这个主题我挺喜欢的&#xff0c;之前也有朋友给我提供过原版主题&#xff0c;一直想要破解但是后来找了几个SG11解密的大哥都表示解密需要大几百大洋&#xff0c;所以一直被搁置了。这个版本是完全解密的&#xff0c;无需SG11加…

ADG901介绍

目录 一、特性二、增强产品特性三、应用四、一般描述五、极低功耗六、引脚描述七、尺寸参数八、电路连接 一、特性 宽带开关&#xff1a;-3 dB 在 4.5 GHz吸收型开关高关断隔离度&#xff1a;在 1 GHz 时为 38 dB低插入损耗&#xff1a;在 1 GHz 时为 0.8 dB单一 1.65 V 至 2.…

QT5:嵌入式linux开发板调用键盘

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录​​​​​​​ 前言 一、Buildroot构建QT环境 1.1 构建环境 1.2 检查qtvirtualkeyboard库 二、测试过程 2.1 直接调用qtvirtualkeyboard 1.测试代码 2.测试效果 2.2 运行…

【Unity国产化信创平台】麒麟银河V10系统虚拟机创建

目录 一、麒麟V10系统镜像下载 二、虚拟机创建流程 三、麒麟银河系统安装流程 一、麒麟V10系统镜像下载 https://www.kylinos.cn/# 官方访问还是会有问题&#xff0c;如果有需要麒麟银河Kylin系统V10的镜像文件&#xff0c;可以留下邮箱或者私信博主获取。 二、虚拟机创…

时间序列分析方法之 -- 移动平均(Moving Average)

目录 原理 适用情况 Python 示例代码 结论 原理 移动平均&#xff08;Moving Average, MA&#xff09;是一种常用的时间序列分析和数据平滑方法。其基本思想是通过取时间序列中某个时间窗口内数据的平均值来消除短期波动&#xff0c;从而更好地揭示数据的长期趋势。根据取平…

【Tomcat】Mac M3 Pro安装Tomcat7

文章目录 下载配置环境变量修改权限启动和关闭 下载 官网&#xff1a;https://tomcat.apache.org/ cd ~/Library tar -zxvf /Users/用户名/Downloads/apache-tomcat-7.0.99.tar.gz mv apache-tomcat-7.0.99 ~/Library/tomcat配置环境变量 vi ~/.bash_profileexport TOMCAT…

UWA Gears正式上线,助力移动平台性能优化

亲爱的开发者朋友们&#xff0c; 我们非常激动地向大家宣布&#xff0c;UWA最新的无SDK性能分析工具 - UWA Gears&#xff0c;现已正式发布&#xff01;无论您使用的是哪种开发引擎&#xff0c;这款工具都能轻松应对&#xff0c;为您的项目保驾护航。更令人心动的是&#xff0c…