Linux消息队列
常用函数
//创建/获取消息队列
int msgget (key_t key, int msgflg);
/*
key : 为键值,ftok();
msgflg:IPC_CREAT - 创建,不存在即创建,已存在即获取,除非… IPC_EXCL - 排斥,已存在即失败。
*/// 向消息队列发送消息
int msgsnd (int msqid, const void* msgp,size_t msgsz, int msgflg);
/*
msqid : msgget()返回
msgp : 包含消息类型和消息数据的内存块.前4个字节必须是一个大于0的整数,代表消息类型,其后消息数据
msgsz:不包括消息类型的,只算消息数据的内存大小
msgflg :IPC_NOWAIT内核中的消息队列缓冲区没有足够的空闲空间时,此函数不会阻塞,而是返回-1
*///从消息队列接收消息
ssize_t msgrcv (int msqid, void* msgp, size_t msgsz,long msgtyp, int msgflg);
/*
msqid : msgget()返回
msgp : 包含消息类型和消息数据的内存块
smgsz:接收的内存大小,如果接收到的内存>smgsz,则只会截取内存大小部分
msgtyp:=0 - 返回消息队列中的第一条消息。 >0 - 若msgflg参数不包含MSG_EXCEPT位,则返回消息队列中第一个类型为msgtyp的消息,若msgflg参数包含MSG_EXCEPT位,则返回消息队列中第一个类型不为msgtyp的消息。 <0 - 返回消息队列中类型小于等于msgtyp的绝对值的消息,若有多个,则取类型最小者。
*///销毁/控制消息队列
int msgctl (int msqid, int cmd, struct msqid_ds* buf);
/*
IPC_STAT
获取消息队列的属性
IPC_SET
设置消息队列的属性
IPC_RMID - 立即删除消息队列。 此时所有阻塞在对该消息队列的,msgsnd和msgrcv函数调用,都会立即返回失败,errno为EIDRM。*/
例子
为了展示例程,部分代码删减,且多个文件合并了,开发过程中,请不要模仿,这样不规范。
server
#include "server.h"
#include "server_function.h"
#include "fileoper.h"
#include "slinklist.h"
#include <stdbool.h>
#include <signal.h>
#include <assert.h>
#include "client.h"/*typedef struct Msg{int type;char msg[1024];
}Msg;typedef struct Back{int type;char msg[1024];
}Back;*/
#define PATH "/home/zhizhen/项目/本地银行"
#define SERVER 100
#define CLIENT 101int id1 ,id2;
Slink list = NULL;
Slink node = NULL;
void myexit(int sig){file_write(list);slink_destory(list);des_msg(id1);des_msg(id2);printf("退出成功\n");exit(0);
}
int server_run(){list = slink_create();assert(list != NULL);file_read(list);int id1 = create_msg(PATH,SERVER);int id2 = create_msg(PATH,CLIENT);assert(id1 != -1 && id2 != -1);while(1){ signal(SIGINT,myexit);Msg msg = {};//后面定义的,接收的消息的结构体Back back = {};int ret = 0;size_t msgsz = 0;//接收消息ssize_t sz = recv_msg(id1,(void *)&msg,sizeof(msg.msg));assert(sz != -1);if(sz == 0){printf("该用户退出了\n"); node = NULL;}int opt = msg.type;switch(opt){case R:msgsz = recv_Reg(&msg,&back,list);break;case E:node = recv_Ent(&msg,&back,list);msgsz = sizeof(B_Ent);break;case G:msgsz = recv_GetM(&msg,&back,list,node);break;case S:msgsz = recv_SaveM(&msg,&back,list,node);break;case T:msgsz = recv_TranM(&msg,&back,list,node);break;case C:msgsz = recv_ChgP(&msg,&back,list,node);break;case D:msgsz = recv_Des(&msg,&back,list,node);break;}Slink next1 = list->next;int i = 1;while(next1 != NULL){Client *p = (Client *)(next1->elem);printf("-------------------\n");printf("*******%d*******\n",i);i++;printf("id:%s\n",p->id);printf("name:%s\n",p->name);printf("password:%s\n",p->password);printf("tel:%s\n",p->tel);printf("money:%d\n",p->money);printf("------------------\n");next1 = next1->next;}ret = send_msg(id2,(const void *)&back,msgsz);//发送反馈assert(ret != -1);}
}
client
#include "client.h"
#include <stdbool.h>
#include <assert.h>static void menu(){printf("--------%d.注册\n",R);printf("--------%d.登录\n",E);printf("--------非%d和%d即:退出\n",R,E);printf(">>>>\n");
}static void menu_Ent(){printf("******%d.取钱\n",G);printf("******%d.充值\n",S);printf("******%d.转账\n",T);printf("******%d.修改密码\n",C);printf("******%d.销户\n",D);printf("*******0.退出\n");printf(">>>>>\n");
}/*typedef struct Msg{int type;char msg[1024];
}Msg;typedef struct Back{int type;char msg[1024];
}Back;*/int create_msg(char *s,int id){key_t key = ftok(s,id);assert(key != -1);return msgget(key,IPC_CREAT|0644);
}
int send_msg(int msqid,const void *msg,size_t msgsz){return msgsnd(msqid,msg,msgsz,0);
}
int recv_msg(int msqid,void *msg,size_t msgsz){return msgrcv(msqid,msg,msgsz,0,0);
}
int des_msg(int msqid){return msgctl(msqid,IPC_RMID,NULL);
}
int client_run(){int id1 = create_msg(PATH,SERVER);int id2 = create_msg(PATH,CLIENT);assert(id1 != -1 && id2 != -1);
Beg:while(1){Msg msg = {};size_t msgsz = 0;Back back = {};int ret = 0;menu();int opt = 0;scanf("%d",&opt);switch(opt){case R:msgsz = send_Reg(&msg);break;case E:msgsz = send_Ent(&msg);break;default:printf("退出成功\n");exit(0);break;}ret = send_msg(id1,(const void *)&msg,msgsz);assert(ret != -1);ret = recv_msg(id2,(void *)&back,sizeof(back.msg));assert(ret != -1);opt = back.type;switch(opt){case R:back_Reg(&back);break;case E:{if(back_Ent(&back) == 1){while(1){menu_Ent();int opt = 0;Msg msg = {};Back back = {};size_t msgsz = 0;scanf("%d",&opt);switch(opt){case G:msgsz = send_GetM(&msg);break;case S:msgsz = send_SaveM(&msg);break;case T:msgsz = send_TranM(&msg);break;case C:msgsz = send_ChgP(&msg);break;case D:msgsz = send_Des(&msg);break;default:goto Beg;printf("退出成功!\n");break;}ret = send_msg(id1,(const void *)&msg,msgsz);assert(ret != -1);ret = recv_msg(id2,&back,sizeof(back.msg));assert(ret != -1);opt = back.type;switch(opt){case G:back_GetM(&back);break;case S:back_SaveM(&back);break;case T:back_TranM(&back);break;case C:back_ChgP(&back);break;case D:back_Des(&back);break;}}}else{printf("登录失败!\n");}break;}}}
}
相关文章:

Linux消息队列
常用函数 //创建/获取消息队列 int msgget (key_t key, int msgflg); /* key : 为键值,ftok(); msgflg:IPC_CREAT - 创建,不存在即创建,已存在即获取,除非… IPC_EXCL - 排斥,已存在即失败。 */// 向消息队列发送消息 int msgs…...

计算机网络——数据链路层(1)
一、概述 在计算机网络中,数据链路层承担着点对点通信的任务,用于跨物理层在网段节点之间参数数据。它在网络分层中处于物理层之上,网路层之下。 在链路层的讨论中,我们将看到两种截然不同类型的链路层信道。第一种类型是广播信道…...

移动端开发进阶之蓝牙通讯(四)
移动端开发进阶之蓝牙通讯(四) 在移动端开发实践中,可能会要求在不同的设备之间切换,从而提升用户体验; 或者为了提升设备的利用率,实现设备之间的连接和协同工作; 不得不通过多端连接,将多个设备连接在一起,实现设备之间的数据共享、远程控制等功能,根据具体的应用…...

npm换源
检查现在的源地址 npm config get registry 使用淘宝镜像 npm config set registry https://registry.npm.taobao.org 使用官方镜像 npm config set registry https://registry.npmjs.org/...

Spring 中 HttpServletRequest 作为成员变量是安全的吗?
在使用spring框架开发的时候,经常会在controller类中看到 HttpServletRequest 对象参数,一般我们都是直接使用,但是它是何时、怎么注入到 spring 容器的呢 ?另外以成员变量注入的 request 是线程安全的吗 ? Controller public c…...

浅聊雷池社区版(WAF)的tengine
雷池社区版是一个开源的免费Web应用防火墙(WAF),专为保护Web应用免受各种网络攻击而设计。基于强大的Tengine,雷池社区版提供了一系列先进的安全功能,适用于中小企业和个人用户。 Tengine的故事始于2011年,…...

如何安装配置VisualSVN服务并实现公网访问本地服务【内网穿透】
文章目录 前言1. VisualSVN安装与配置2. VisualSVN Server管理界面配置3. 安装cpolar内网穿透3.1 注册账号3.2 下载cpolar客户端3.3 登录cpolar web ui管理界面3.4 创建公网地址 4. 固定公网地址访问 前言 SVN 是 subversion 的缩写,是一个开放源代码的版本控制系统…...

解析TZ字样的0时区UTC时间格式化为东八区
带TZ字样的0时区UTC时间格式化为东八区 TZ 的Z是zero timezone 0时区的意思。带TZ的时间是UTC0的时间SimpleDateFormat默认使用系统日历时区,必须手动指定0时区,才能正确解析TZ时间详细测试代码见下: SneakyThrows public static void main…...

python两数之和
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。 你可以按任意顺序返回…...

PBR材质背光面太暗优化
图形学中漫反射光照遵循兰伯特光照模型,它的公式如下 其中: :漫反射光颜色 :入射光颜色 :材质的漫反射系数 :法线方向 :光源方向 由于背光面的法线方向和光源方向的点积为负数,因此…...

【电力电子在电力系统中的应用】6 滞环电流控制的PWM整流器 + STATCOM整流器 + APF仿真
【仅供参考】 【2023.06西南交大电力电子在电力系统中的应用】 目录 步骤一:基于滞环电流控制的PWM整流器仿真 1.1 仿真要求 1.2 仿真电路原理及设计 1.2.1 主电路的搭建 1.2.2 控制电路的搭建 1.3 波形分析 步骤二:从PWM整流器到STATCOM仿真 2…...

接近8000字的SpringSpring常用注解总结!安排
接近8000字的Spring/Spring常用注解总结!安排 为什么要写这篇文章? 最近看到网上有一篇关于 SpringBoot 常用注解的文章被转载的比较多,我看了文章内容之后属实觉得质量有点低,并且有点会误导没有太多实际使用经验的人ÿ…...

51单片机_智能家居终端
实物演示效果: https://www.bilibili.com/video/BV1bh4y1A7ZW/?vd_source6ff7cd03af95cd504b60511ef9373a1d 51单片机是否适合做多功能智能家居控制系统?51单片机的芯片是否具有与WiFi通信的能力?如果有的话,具体有哪些芯片啊&a…...

css实现动态水波纹效果
效果如下: 外层容器 (shop_wrap): 设置外边距 (padding) 提供一些间距和边距 圆形容器 (TheCircle): 使用相对定位 (position: relative),宽度和高度均为 180px,形成一个圆形按钮圆角半径 (border-radius) 设置为 50%&…...

Chrome 开发者工具
Chrome 开发者工具 介绍控制面板时间线下载信息概要请求列表单个请求时间线优化时间线上耗时项 lighthouse 插件Performance(性能指标)Accessibility(可访问性)Best Practices(最佳实践)SEO(搜索…...

Error: error:0308010C:digital envelope routines::unsupported的解决方案
因为最近安装了pnpm对node版本有要求,升级了node版本是18以后,在运行之前的项目,就跑不起来了,报错如下: Error: error:0308010C:digital envelope routines::unsupported解决方案一: node版本切换到16版…...

vue基于spring boot框架的发艺美发店理发店管理系统的设计q9xpe
店铺信息、美发信息是发艺美发店管理系统的重要组成部分,信息清晰、详细、准确,能够有效地促进发艺美发店管理系统的运行[5]。基础设定函数是对整个系统的总体布局进行合理安排,包括:店铺活动、物品信息、领用信息等。通过对各类资…...

JS取余运算符 %,ES2023 新增数组方法Array.at
取余运算符(%)的作用就是用来两个操作数进行相除运算之后的余数。 注意,两个操作数取余是有循环范围的,这个范围为 0 - 第二个参数 - 1。 如下图: 对于6取余的话,得到的取余数据就会一直在0-5之间进行循环…...

unity SqLite读取行和列
项目文件 链接:https://pan.baidu.com/s/1BabHvQ-y0kX_w15r7UvIGQ 提取码:emsg –来自百度网盘超级会员V6的分享 using System.Collections; using System.Collections.Generic; using UnityEngine; using Mono.Data.Sqlite; using System; using Syste…...

使用docker部署RStudio容器并结合内网穿透实现公网访问
文章目录 前言1. 安装RStudio Server2. 本地访问3. Linux 安装cpolar4. 配置RStudio server公网访问地址5. 公网远程访问RStudio6. 固定RStudio公网地址 前言 RStudio Server 使你能够在 Linux 服务器上运行你所熟悉和喜爱的 RStudio IDE,并通过 Web 浏览器进行访问…...

adb wifi 远程调试 安卓手机 命令
使用adb wifi 模式调试需要满足以下前提条件: 手机 和 PC 需要在同一局域网下。手机需要开启开发者模式,然后打开 USB 调试模式。 具体操作步骤如下: 将安卓手机通过 USB 线连接到 PC。(连接的时候,会弹出请求&#x…...

Android Activity的启动流程(Android-10)
前言 在Android开发中,我们经常会用到startActivity(Intent)方法,但是你知道startActivity(Intent)后Activity的启动流程吗?今天就专门讲一下最基础的startActivity(Intent)看一下Activity的启动流程,同时由于Launcher的启动后续…...

flask不使用flask-login插件
由于flask版本升级问题,flask-manager里面的Command命令高版本不支持,低版本的兼容flask-sqlalchemy启动也会报错,第三方插件有很多问题,所以痛定思痛决定放弃使用这个,使用flask自带语法自己写一个 类似于django继承…...

1. SpringBoot3 基础
文章目录 1. SpringBoot 概述2. SpringBoot 入门3. SpringBoot 配置文件3.1 SpringBoot 配置文件基本使用3.2 yml 配置文件 4. SpringBoot 整合 Mybatis5. Bean 管理5.1 Bean 扫描5.2 Bean 注册5.3 注册条件 6. 组合注解7. 自动配置原理8. 自定义 Starter 1. SpringBoot 概述 …...

美易官方:苹果承认GPU安全漏洞存在:iPhone 12和M2系列受影响
苹果承认GPU安全漏洞存在: iPhone 12和M2 MacBook Air受影响 近日,苹果公司承认其部分产品存在GPU安全漏洞,这些漏洞可能会影响iPhone 12和M2 MacBook Air等设备的安全性。这一消息引起了广泛的关注和担忧,因为这些设备是许多用户…...

【Vue3】3-1 : 章节介绍 - Vue3组件应用及单文件组件
本书目录:点击进入 一、本章学习目标 二、课程安排 一、本章学习目标 Vue3组件相关概念掌握组件之间的通信封装一个可复用的组件单文件组件SFC:即.vue文件 样式 结构 逻辑脚手架的使用和底层实现机制工程化的认知 二、课程安排 组件的概念及组件的基…...

【数据结构】二叉树(遍历,递归)
🌈个人主页:秦jh__https://blog.csdn.net/qinjh_?spm1010.2135.3001.5343🔥 系列专栏:《数据结构》https://blog.csdn.net/qinjh_/category_12536791.html?spm1001.2014.3001.5482 目录 二叉树遍历规则 前序遍历 …...

《微信小程序开发从入门到实战》学习八十五
6.15 设备API 6.15.2 添加联系人API 使用wx.addPhoneContact接口可以在用户的手机通讯录中添加联系人信息。用户可以选择“新增联系人”或“添加到已有联系人”。该接口接受Object参数,参支持属性如下所示: firstName:必填,名字…...

设计模式——命令模式
命令模式(Command Pattern)是一种行为型设计模式,它将一个请求封装为一个对象,使发出请求的对象和执行请求的对象解耦。这样可以方便地对请求排队、记录日志、撤销/重做操作以及支持可扩展性。 原理 命令接口(Comman…...

Modbus协议学习第三篇之协议通信规则
导语 本篇博客将深入介绍Modbus协议的一些内容,主要包括通讯方式和通讯模型的介绍 Modbus通讯方式 Modbus协议是单主机、多从机的通信协议,即同一时间,总线上只能有一个主设备,但可以有一个或者多个从设备(最多好像是2…...