IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> unix环境高级编程消息队列应用---本地银行C语言 -> 正文阅读

[C++知识库]unix环境高级编程消息队列应用---本地银行C语言

本地银行

结构体 account.h

#ifndef _ACCOUNT_H__
#define _ACCOUNT_H__

//客户端 操作  一个操作对应一个消息类型  服务器返回同样的消息类型
enum OPER{OPEN=1,LOGIN,GETM,SAVEM,MOVEM,PASS,CHECK,DEST,QUIT};

#define CARD_NO_LEN 16
#define PASS_LEN 6
#define NAME_LEN 48
#define ID_LEN 18
#define TEL_LEN 12
typedef struct Account{
	char cardNo[CARD_NO_LEN]; //账户  自动生成的
	char pass[PASS_LEN];      //密码
	char name[NAME_LEN];      //姓名
	char id[ID_LEN];          //身份证号码
	char tel[TEL_LEN];        //联系方式
	float balance;            //余额
}Account;

typedef struct OpenRet{
	int status;               //开户成功或者失败
	char cardNo[CARD_NO_LEN]; //账号
}OpenRet;

typedef struct Login{
	char cardNo[CARD_NO_LEN];
	char pass[PASS_LEN];
}Login;

typedef struct LoginRet{
	int status;              //登录成功或者失败
	struct Account act;      //返回登录的帐户所有信息
}LoginRet;

typedef struct GetM{
	float money;	
}GetM;

typedef struct GetMRet{
	int status;
	float balance;
}GetMRet;

typedef struct SaveM{
	float money;
}SaveM;

typedef struct SaveMRet{
	int status;
	float balance;
}SaveMRet;

typedef struct MoveM{
	char destCardNo[CARD_NO_LEN];   //对方账户
	float money;
}MoveM;

typedef struct MoveMRet{
	int status;
	float balance;
}MoveMRet;

typedef struct Pass{
	char pass[PASS_LEN];	
}Pass;

typedef struct Ret{
	int status;
}Ret;


#endif //_ACCOUNT_H__

business.h

#ifndef _BUSINESS_H__
#define _BUSINESS_H__

#include <stdio.h>
#include "msgque.h"
#include "account.h"

size_t business_entry(struct Msg *msg);

#endif //_BUSINESS_H__

business.c

#include "business.h"
#include "log.h"
#include "open.h"
#include "login.h"
#include "run.h"



size_t business_entry(struct Msg *msg)
{
	LOG_ERROR("msgtype:%d\n",msg->type);
	static Account *pact = NULL;    //记录登录的服务器
	size_t size = 0;
	if(pact == NULL)
	{
		switch(msg->type)
		{
			case OPEN: msg_open();
			case LOGIN:	msg_login();
			default:	
			break;
		}
	}
	else
	{
		switch(msg->type)
		{
			case GETM: msg_getm(struct Msg *msg);
			case SAVEM:msg_savem(struct Msg *msg);
			case MOVEM:msg_movem(struct Msg *msg);
			case PASS:msg_pass(struct Msg *msg);
			case DEST:msg_dest(struct Msg *msg);
			case CHECK:msg_check(struct Msg *msg);
			case QUIT:
				pact = NULL;
			default:
		}
	}
	return size;	
}

login.h

#ifndef _LOGIN_H__
#define _LOGIN_H__

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <fcntl.h>
#include <signal.h>
#include "account.h"

#endif //_LOGIN_H__

login.c

#include "login.h"
#include "useroper.h"
	static int msgid1;
	static int msgid2;
	msgid1 = msg_create(PATH,PRO1);
	msgid2 = msg_create(PATH,PRO2);

	while(1)
	{
		struct Msg msg={};
		msgrcv(msgid1,&msg,sizeof(Msg),7,0);
		struct Account account;
		Account *account = (Account*)msg->msg;
		char filename[100]={".dat"};
		sprintf(filename,"/home/zhizhen/2021/01sc/wl/banksys/%d.dat",account->id);
		if(access(filename,F_OK) == -1)
		{
			account->id = -2;
            msgsnd(msgid2,&account,sizeof(Msg),0);
            continue;
        }
		int fd = open(filename,O_RDWR,0644);
		if(fd < 0)
		{
			account->id = -1;
			msgsnd(msgid2,&account,sizeof(Msg),0);
		}
		if(read(fd,&Account,sizeof(Account)) < 0)
		{
			return -1;
		}
		if(0 == strcmp(Account.pass,accont->pass) && Account.id == account->id)
		{
			lseek(fd,0,SEEK_SET);	
        	write(fd,&Account,sizeof(Account));
			close(fd);#include "login.h"
#include "useroper.h"
	static int msgid1;
	static int msgid2;
	msgid1 = msg_create(PATH,PRO1);
	msgid2 = msg_create(PATH,PRO2);

	while(1)
	{
		struct Msg msg={};
		msgrcv(msgid1,&msg,sizeof(Msg),7,0);
		struct Account account;
		Account *account = (Account*)msg->msg;
		char filename[100]={".dat"};
		sprintf(filename,"/home/zhizhen/2021/01sc/wl/banksys/%d.dat",account->id);
		if(access(filename,F_OK) == -1)
		{
			account->id = -2;
            msgsnd(msgid2,&account,sizeof(Msg),0);
            continue;
        }
		int fd = open(filename,O_RDWR,0644);
		if(fd < 0)
		{
			account->id = -1;
			msgsnd(msgid2,&account,sizeof(Msg),0);
		}
		if(read(fd,&Account,sizeof(Account)) < 0)
		{
			msgsnd(msgid2,&account,sizeof(Msg),0);
		}
		else
		{
				account->id = -1;				
        		write(fd,&use,sizeof(Account));
        		close(fd);
				msgsnd(msgid2,&account,sizeof(Msg),0);
		}					
		}
	}

客户端 client.h

#ifndef _CLIENT_H__
#define _CLIENT_H__

void client_run(void);

#endif //_CLIENT_H__

client.c

#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include "client.h"
#include "log.h"
#include "msgque.h"

#define PATH "/"
#define PRO1 100
#define PRO2 101

void client_run(void){
	pLogFile = stdout;
	//init();//初始化工作	
	int msgidw = msg_create(PATH,PRO1);
	int msgidr = msg_create(PATH,PRO2);
	if(msgidw==-1||msgidr==-1){
		exit(-1);	
	}
	Msg msg = {};
	size_t msgsz = 0;
	int ret = 0;
	while(true){
		//读取用户的信息输入
		msgsz = read_msg(&msg);
		ret = msg_send(msgidw,&msg,msgsz);
		if(ret == -1 || msg.type==0){
			break;	
		}
		ret = msg_recv(msgidr,&msg,0);
		analyze_msg(&msg);//服务器返回的结果
	}
}

main.c

#include "client.h"

int main(){
	client_run();
	return 0;	
}

useroper.h

#ifndef _USER_OPER_H__
#define _USER_OPER_H__

#include "msgque.h"

size_t read_msg(struct Msg *msg);
void analyze_msg(struct Msg *msg);


#endif //_USER_OPER_H__

useroper.c

#include "useroper.h"
#include "account.h"

//跟用户交互 组装发给服务器的数据  返回要发给服务器数据的字节数
size_t read_msg(struct Msg *msg){
	static int login = 0;
	if(login == 0){
		//menu();	//开户  登录    登录
		int opt = 0;
		scanf("%d",&opt);//opt  3
		if(opt!=OPEN&&opt!=LOGIN)
				return -1;
		msg->type = opt;
		switch(opt){
			case OPEN:
				
				return sizeof(Account);
			case LOGIN:
				
				return sizeof(Login);
		}
	}else{
		//oper_menu();	
		int opt = 0;
		scanf("%d",&opt);
		msg->type = opt+2;
		if(msg->type < GETM || msg->type > QUIT)
			return -1;
		switch(msg->type){
			case GETM:	
			case SAVEM:
			case MOVEM:
			case PASS:
			case CHECK:
			case DEST:
			case QUIT://给服务器发个消息
				break;
		}
	}

}
//解析服务器返回的数据
void analyze_msg(struct Msg *msg){
	switch(msg->type){
		case OPEN:
		case LOGIN:
		case GETM:
		case SAVEM:
		case PASS:
		case CHECK:
		case DEST:
		case QUIT:
			break;
	}
}


msgque.h

#ifndef _MSG_QUE_H__
#define _MSG_QUE_H__

#include <stdio.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include "log.h"

#define MSG_MAX_LEN 1024
//msgrcv   msgsnd 第二个参数  Msg msg;  &msg;
typedef struct Msg{
	int type;	
	char msg[MSG_MAX_LEN];
}Msg;

int msg_create(const char *path,int proId);
int msg_send(int msgid,struct Msg *msg,size_t msgsz);
int msg_recv(int msgid,struct Msg *msg,int msgtype);
int msg_remove(int msgid);

#endif //_MSG_QUE_H__

msgque.c

#include <string.h>
#include <errno.h>
#include "msgque.h"
/*
#define MSG_MAX_LEN 1024
//msgrcv   msgsnd 第二个参数  Msg msg;  &msg;
typedef struct Msg{
	int type;	
	char msg[MSG_MAX_LEN];
}Msg;
*/
int msg_create(const char *path,int proId){
	key_t key = ftok(path,proId);
	if(key == -1){
		LOG_FATAL("ftok: %s\n",strerror(errno));
		return -1;
	}
	int msgid = msgget(key,IPC_CREAT|0660);
	if(msgid == -1){
		LOG_FATAL("msgget: %s\n",strerror(errno));
		return -1;
	}
	return msgid;
}
int msg_send(int msgid,struct Msg *msg,size_t msgsz){
	int ret = msgsnd(msgid,(const void*)msg,msgsz,0);//阻塞
	if(ret == -1){
		LOG_ERROR("msgsnd: %s\n",strerror(errno));	
	}
	return ret;
}
int msg_recv(int msgid,struct Msg *msg,int msgtype){
	int ret = msgrcv(msgid,(void *)msg,MSG_MAX_LEN-1,msgtype,0);//阻塞 只读消息队列中的第一条信息
	if(ret == -1){
		LOG_ERROR("msgrcv: %s\n",strerror(errno));	
	}
	return ret;
}
int msg_remove(int msgid){
	int ret = msgctl(msgid,IPC_RMID,NULL);
	if(ret == -1){
		LOG_ERROR("msgctl: %s\n",strerror(errno));	
	}
	return ret;
}

服务器servermain.c

#include "server.h"

int main(){
	server_run();
	return 0;	
}

server.h

#ifndef _SERVER_H__
#define _SERVER_H__

void server_run(void);

#endif //_SERVER_H__

server.c

#include <stdbool.h>
#include <stdlib.h>
#include <errno.h>

#include "server.h"
#include "log.h"
#include "msgque.h"
#include "business.h"

#define PATH "/"
#define PROID1 100
#define PROID2 101

void init(void){
	//init_config();	
	pLogFile = stdout;
	//load_data();
}

void server_run(void){
	init();//初始化  加载配置文件 加载基础数据  创建消息队列
	int msgidr = msg_create(PATH,PROID1);
	int msgidw = msg_create(PATH,PROID2);
	if(msgidr == -1 ||msgidw == -1){
		exit(-1);	
	}
	Msg msg = {};
	int ret = 0;
	size_t msgsz = 0;
	while(true){
		//从消息队列中读取一条消息
		ret = msg_recv(msgidr,&msg,0);//接收消息
		msgsz = business_entry(&msg);//msg作为入参 也作为出参 业务处理
		ret = msg_send(msgidw,&msg,msgsz);//回消息 返回结果
	}
		
}

单链表.h

#ifndef SLINKED_LIST_H__

#define SLINKED_LIST_H__



#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <stdbool.h>



typedef struct Node{

	void *pelem;          //malloc

	struct Node *next;    //???¢??ò????áμ?μ????? 

}SNode;





typedef struct SLinkedList{

	struct Node *head;    //í·?áμ?

	size_t elemSize;      //?????a??μ??óD?

	size_t size;          //á?±í?a??μ???êy 

}*SLinkedList; 



#define NODESIZE  sizeof(struct Node)

#define LISTSIZE  sizeof(struct SLinkedList)



SLinkedList slinked_list_create(size_t elemSize);

bool slinked_list_empty(SLinkedList list);

size_t slinked_list_size(SLinkedList list);

void slinked_list_clear(SLinkedList list);

void slinked_list_destroy(SLinkedList list);

void slinked_list_travel(SLinkedList list,void (*travel)(const void *));

int slinked_list_insert(SLinkedList list,size_t pos,const void *pelem);

int slinked_list_delete(SLinkedList list,size_t pos,void *pelem);

int slinked_list_get(SLinkedList list,size_t pos,void *pelem);

void *slinked_list_index(SLinkedList list,size_t pos); 

void *slinked_list_find(SLinkedList list,const void *key,int (*cmp)(const void*,const void*));

int slinked_list_remove(SLinkedList list,const void *key,int (*cmp)(const void*,const void*));



#endif //SLINKED_LIST_H__


单链表.c

#include "slinkedlist.h"

/*

typedef struct Node{

	void *pelem;          //malloc

	struct Node *next;    //???¢??ò????áμ?μ????? 

}SNode;





typedef struct SLinkedList{

	struct Node *head;    //í·?áμ?

	size_t elemSize;      //?????a??μ??óD?

	size_t size;          //á?±í?a??μ???êy 

}*SLinkedList; 

*/

//SLinkedList list = slinked_list_create(8); 

SLinkedList slinked_list_create(size_t elemSize){

	SLinkedList list = (SLinkedList)malloc(LISTSIZE);

	if(list == NULL){

		return NULL;

	}

	list->head = (struct Node*)malloc(NODESIZE);//í·?áμ?

	if(list->head == NULL){

		free(list);

		return NULL;

	} 

	list->head->next = NULL;

	list->elemSize = elemSize;

	list->size = 0;

	return list;

}

bool slinked_list_empty(SLinkedList list){

	return list->size == 0;

}

size_t slinked_list_size(SLinkedList list){

	return list->size;

}

void slinked_list_clear(SLinkedList list){

	struct Node *node = list->head->next;//μúò????áμ? 

	struct Node *next = NULL;

	while(node != NULL){

		next = node->next;

		free(node->pelem);   //êí·????¢êy?Y?a??μ??ú?????? 

		free(node);          //êí·??áμ?μ??ú?????? 

		node = next; 

	} 

	list->head->next = NULL;

	list->size = 0;

}

void slinked_list_destroy(SLinkedList list){

	slinked_list_clear(list);

	free(list->head);//list->head = NULL; list->size = 0; 

	free(list);

}

void slinked_list_travel(SLinkedList list,void (*travel)(const void *)){

	struct Node *node = list->head->next;

	for(;node!=NULL;node = node->next){

		travel(node->pelem);

	}

}

//pos [1,...]

static struct Node *slinked_list_get_prev_node(SLinkedList list,size_t pos){

	struct Node *node = list->head;

	size_t i;

	for(i=0;node!=NULL&&i<pos;i++){

		node = node->next;

	}

	return node;

} 

int slinked_list_insert(SLinkedList list,size_t pos,const void *pelem){

	struct Node *prev = slinked_list_get_prev_node(list,pos);

	if(prev == NULL){

		return -1;

	}

	struct Node *node = (struct Node*)malloc(NODESIZE);

	if(node == NULL){

		return -2;

	}

	node->pelem = malloc(list->elemSize);

	if(node->pelem == NULL){

		free(node);

		return -3;

	}

	memcpy(node->pelem,pelem,list->elemSize);//?ú????±? 

	node->next = prev->next;

	prev->next = node;

	list->size++;

	return 0;

}

int slinked_list_delete(SLinkedList list,size_t pos,void *pelem){

	struct Node *prev = slinked_list_get_prev_node(list,pos);

	if(prev==NULL||prev->next==NULL){

		return -1;

	} 

	struct Node *curr = prev->next;

	memcpy(pelem,curr->pelem,list->elemSize);

	prev->next = curr->next;

	--list->size;

	free(curr->pelem);//???¢êy?Yμ??ú???éò?êí·?á?

	free(curr);

	return 0;

}

int slinked_list_get(SLinkedList list,size_t pos,void *pelem){

	struct Node *curr = slinked_list_get_prev_node(list,pos+1);

	if(curr == NULL){

		return -1;

	}

	memcpy(pelem,curr->pelem,list->elemSize);

	return 0;

}

void *slinked_list_index(SLinkedList list,size_t pos){

	struct Node *node = slinked_list_get_prev_node(list,pos);

	if(node == NULL){

		return NULL;

	}

	return node->pelem;

}



void *slinked_list_find(SLinkedList list,const void *key,int (*cmp)(const void*,const void*)){

	struct Node *node = list->head->next;

	for(;node!=NULL;node = node->next){

		if(cmp(key,node->pelem)==0){

			return node->pelem;

		}

	}

	return NULL;

}



int slinked_list_remove(SLinkedList list,const void *key,int (*cmp)(const void*,const void*)){

	struct Node *node = list->head->next;//????????

	struct Node *prev = list->head;//??????????

	for(;node!=NULL;prev = node,node = node->next){

		if(cmp(key,node->pelem) == 0){

			prev->next = node->next;

			free(node->pelem);

			free(node);

			return 0;

		}

	}

	return -1;

}








  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-13 11:45:37  更:2021-08-13 11:48:47 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/21 4:48:21-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码