当前位置: 首页 > 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;
}

相关文章:

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

我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎…...

放大电路总结

补充: 只有直流移动时才有Rbe动态等效电阻 从RsUs看进去,实际上不管接了什么东西都能够看成是一个Ri(输入电阻) Ri Ui/Ii Rb//Rbe Ui/Us Ri/(RiRs) Aus (Uo/Ui)*(Ui/Us) Au *Ri/(RiRs) 当前面是一个电压源的信号 我们就需要输入电阻更大 Ro--->输出电阻--->将…...

深度学习1-简介

人工智能&#xff08;AI&#xff09;旨在打造模仿智能行为的系统。它覆盖了众多方法&#xff0c;涵盖了基于逻辑、搜索和概率推理的技术。机器学习是 AI 的一个分支&#xff0c;它通过对观测数据进行数学模型拟合来学习决策制定。这个领域近年来迅猛发展&#xff0c;现在几乎&a…...

Java基础语法 (基础介绍 二)

目录 Java 基础语法 第一个Java程序 基本语法 Java标识符 Java修饰符 Java变量 Java关键字 Java注释 Java 空行 Java 对象和类 Java中的对象 Java中的类 构造方法 创建对象 访问实例变量和方法 实例 源文件声明规则 Java包 Import语句 一个简单的例子 Java…...

SAPUI5基础知识18 - 自定义CSS和主题色

1. 背景 在上一篇博客中&#xff0c;我们通过使用SAPUI5提供的CSS类实现元素间距的调整。在本篇博客中&#xff0c;让我们看一下如何实现自定义的CSS样式。 2. 背景知识 2.1 CSS基础语法 CSS&#xff0c;全称为级联样式表&#xff08;Cascading Style Sheets&#xff09;&a…...

Postman中API测试的艺术:测试用例复用的高级技巧

Postman中API测试的艺术&#xff1a;测试用例复用的高级技巧 在API测试过程中&#xff0c;复用测试用例可以显著提高测试效率和一致性。Postman作为一个强大的API开发工具&#xff0c;提供了多种机制来实现测试用例的复用。本文将深入探讨Postman中API测试用例复用的技巧&…...

Flutter Geocoding插件使用指南:简化地理编码与逆地理编码

Flutter Geocoding插件使用指南&#xff1a;简化地理编码与逆地理编码 简介 geocoding 是一个Flutter插件&#xff0c;提供了简便的地理编码&#xff08;将地址转换为经纬度坐标&#xff09;和逆地理编码&#xff08;将经纬度坐标转换为地址&#xff09;功能。它利用了iOS和A…...

“手撕”全网最细的JDBC教程(安装导入使用)

目录 一、什么是JDBC 二、JDBC的安装 三、JDBC如何导入 四、怎么使用JDBC编写代码 一、什么是JDBC JDBC由Java提供给数据库的一组通用的API。 在平常的业务中&#xff0c;是比较少使用像cmd命令行来操作数据库的&#xff0c;更多的是操作代码&#xff08;Python&#xff…...

C++指针选择题带答案

1、有如下语句int a10,b20,*p1,*p2;p1&a;p2&b;如图1所示&#xff0c;若要实现图2所示的存储 结构&#xff0c;可选用的赋值语句是___________。 A)*p1*p2; B)p1p2; C&#xff09;p1*p2; D)*p1p2; 2、变量的指针&#xff0c;其含义是该…...

力扣 二分查找

二分查找基础篇。 题目 class Solution {public int searchInsert(int[] nums, int target) {int l 0, r nums.length - 1;while(l < r) {int mid l((r-l)>>1);//(lr)/2if(nums[mid]<target)lmid1;else rmid-1;}return l;//处理边界&#xff0c;设定数组的左半…...

ADMAS-Simulink联合仿真输入设置

使用Solidworks、ADAMS、Simulink进行机电联合仿真_adams-simulink-CSDN博客RecurDynSimulink联合仿真案例演示_哔哩哔哩_bilibili# C#调用已经使用Python训练好的神经网络做图片检测_c#调用python训练好的神经网络模型-CSDN博客...

【NOI】C++程序设计入门三

文章目录 前言一、大杂烩1.导入2.常量3.标识符4.关键字5.整型补充5.1 short&#xff1a;短整型5.2 long&#xff1a;长整型5.3 long long&#xff1a;长长整型 二、例题讲解问题&#xff1a;1597. 买文具问题&#xff1a;1596. 火柴棒三角形问题问题&#xff1a;1417. 买文具问…...

Three.js投射光线实现三维物体交互

<template><div id"webgl"></div> </template><script setup> import * as THREE from three //导入轨道控制器 import { OrbitControls } from three/examples/jsm/controls/OrbitControls // 导入 dat.gui import { GUI } from thre…...

SSRF学习笔记

1.NAT学习 Nat&#xff08;Network Address Translation&#xff0c;网络地址转换&#xff09;是 一种网络通信技术主要用于将私有网络中的内部IP地址转换成公共网络中的公共IP地址&#xff0c;以实现局域网内部设备访问互联网的功能。具体来说&#xff0c;Nat有以下几个主要…...

Python——Pandas(第三讲)

文章目录 修改替换变量值对应数值的替换指定数值范围的替换 虚拟变量变换数值变量分段数据分组基于拆分进行筛选 分组汇总使用 agg 函数进行汇总引用自定义函数 长宽格式转换转换为最简格式长宽型格式的自由互转 多个数据源的合并数据的横向合并concat 命令 处理缺失值认识缺失…...

性能测试中qps 一直上不去的原因

QPS&#xff1a;Queries Per Second意思是“每秒查询率”&#xff0c;是一台服务器每秒能够相应的查询次数&#xff0c;是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准。 在性能测试中&#xff0c;QPS&#xff08;每秒查询率&#xff09;一直上不去可能由以下…...

学习笔记14:CNAME 记录值、TTL (Time to Live)、Redis 的 Pool 对象池、钩子函数、依赖注入

CNAME 记录值 CNAME 记录是一种DNS记录类型&#xff0c;它将一个域名映射到另一个域名。这通常用于将一个子域名指向另一个域名&#xff0c;或者将一个域名指向一个不同的顶级域。 用途&#xff1a;用于域名别名&#xff0c;负载均衡&#xff0c;或者在更换域名时保持服务的连…...

springboot集成mybatis时,dao层的mapper类需要添加@Repository注解吗?

在Spring Boot项目中&#xff0c;当你使用MyBatis作为ORM框架时&#xff0c;关于DAO层的Mapper类是否需要添加Repository注解&#xff0c;这主要取决于你的项目需求和配置。 Repository注解的作用Repository注解是Spring框架中用于声明持久层&#xff08;DAO层&#xff09;的组…...

一文总结代理:代理模式、代理服务器

概述 代理在计算机编程领域&#xff0c;是一个很通用的概念&#xff0c;包括&#xff1a;代理设计模式&#xff0c;代理服务器等。 代理类持有具体实现类的实例&#xff0c;将在代理类上的操作转化为实例上方法的调用。为某个对象提供一个代理&#xff0c;以控制对这个对象的…...

探索 Kubernetes 持久化存储之 Longhorn 初窥门径

作者&#xff1a;运维有术星主 在 Kubernetes 生态系统中&#xff0c;持久化存储扮演着至关重要的角色&#xff0c;它是支撑业务应用稳定运行的基石。对于那些选择自建 Kubernetes 集群的运维架构师而言&#xff0c;选择合适的后端持久化存储解决方案是一项至关重要的选型决策。…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 &#xff08;1&#xff09;连接查询&#xff08;JOIN&#xff09; 内连接&#xff08;INNER JOIN&#xff09;&#xff1a;返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

STM32+rt-thread判断是否联网

一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统

目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索&#xff08;基于物理空间 广播范围&#xff09;2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

Fabric V2.5 通用溯源系统——增加图片上传与下载功能

fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...

在 Spring Boot 项目里,MYSQL中json类型字段使用

前言&#xff1a; 因为程序特殊需求导致&#xff0c;需要mysql数据库存储json类型数据&#xff0c;因此记录一下使用流程 1.java实体中新增字段 private List<User> users 2.增加mybatis-plus注解 TableField(typeHandler FastjsonTypeHandler.class) private Lis…...

认识CMake并使用CMake构建自己的第一个项目

1.CMake的作用和优势 跨平台支持&#xff1a;CMake支持多种操作系统和编译器&#xff0c;使用同一份构建配置可以在不同的环境中使用 简化配置&#xff1a;通过CMakeLists.txt文件&#xff0c;用户可以定义项目结构、依赖项、编译选项等&#xff0c;无需手动编写复杂的构建脚本…...

【UE5 C++】通过文件对话框获取选择文件的路径

目录 效果 步骤 源码 效果 步骤 1. 在“xxx.Build.cs”中添加需要使用的模块 &#xff0c;这里主要使用“DesktopPlatform”模块 2. 添加后闭UE编辑器&#xff0c;右键点击 .uproject 文件&#xff0c;选择 "Generate Visual Studio project files"&#xff0c;重…...

【Vue】scoped+组件通信+props校验

【scoped作用及原理】 【作用】 默认写在组件中style的样式会全局生效, 因此很容易造成多个组件之间的样式冲突问题 故而可以给组件加上scoped 属性&#xff0c; 令样式只作用于当前组件的标签 作用&#xff1a;防止不同vue组件样式污染 【原理】 给组件加上scoped 属性后…...