图书管理系统的服务器(ubuntu)--使用expoll

头文件:

#ifndef __HEAD_H__
#define __HEAD_H__
#include <stdio.h>
#include <errno.h>       //错误码的头文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>      //open的头文件
#include <unistd.h>     //close\sleep的头文件
#include <string.h>     //str系列函数头文件
#include <math.h>       //数学头文件
#include <stdlib.h>     //标准库文件
#include <time.h>       //时间头文件
#include <dirent.h>    //目录操作头文件
#include <sys/wait.h>   //进程回收 
#include <pthread.h>   //关于线程操作的头文件
#include <semaphore.h>  //信号量头文件
#include <signal.h>     //信号的头文件
#include <sys/ipc.h>   //system V进程通信头文件
#include <sys/msg.h>  //消息队列头文件
#include <sys/shm.h>  //共享内存头文件
#include <sys/sem.h>  //信号灯集头文件
#include <arpa/inet.h>  //字节序转换函数
#include <sys/socket.h>
#include <netinet/in.h>   //点分十进制--网络字节序的操作头文件
#include <linux/input.h>
#include <sys/epoll.h>
#include <poll.h>    //监测集合中文件描述符的头文件
#include <sys/un.h>  //域套接字头文件
#include <sqlite3.h> //数据库头文件
#define ERR_MSG(msg) do{printf("%s:%s:%d\n",__FILE__,__func__,__LINE__);\
	perror(msg);\
	return -1;}while(0)



#endif

源文件:

#include "head.h"
#define IP "192.168.125.170 "
#define PORT 8888
/*
typedef union epoll_data {
	void        *ptr;
	int          fd;
	uint32_t     u32;
	uint64_t     u64;
} epoll_data_t;
 
struct epoll_event {
	uint32_t     events;      	
	epoll_data_t data;        
};
*/
struct message{
	char head[20];
	char msg[128];
	char name[32];
};
sqlite3* db_books = NULL;
int epfd=0;
int create_table(sqlite3* db_books); 
int determine_member(int cfd,struct message cli_buf);
int search(int cfd,struct message cli_buf);
int add_book(int cfd,struct message cli_buf);
int update(int cfd,struct message cli_buf);
int delete(int cfd,struct message cli_buf);
int search_history(int cfd);
int borrow_books(int cfd,struct message cli_buf);
int return_books(int cfd,struct message cli_buf);
int main(int argc, const char *argv[])
{
	//打开数据库,并创建人员信息表,图书信息表,借阅信息表
	if(sqlite3_open("./books.db",&db_books) != SQLITE_OK)
	{
		printf("errmsg:%s\n",sqlite3_errmsg(db_books));
		fprintf(stderr,"__%d__ sqlite3_open failed\n",__LINE__);
		return -1;
	}
	printf("打开数据库成功\n");
	create_table(db_books);

	//创建流式套接字
	int sfd = socket(AF_INET,SOCK_STREAM,0);
	if(sfd<0)
	{
		ERR_MSG("socket");
	}
	printf("socket success\n");
	//允许端口快速被重用
	int reuse=1;
	if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))<0)
	{
		ERR_MSG("setsockopt");
	}
	printf("setsockopt success\n");
 
	//填充服务器的ip和端口
	struct sockaddr_in sin;
	sin.sin_family=AF_INET;
	sin.sin_port=htons(PORT);
	sin.sin_addr.s_addr=inet_addr(IP);
 
	//绑定服务器的地址信息
	if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))<0)
	{
		ERR_MSG("bind");
	}
	printf("bind success\n");
 
	//设置套接字为被动监听状态
	if(listen(sfd,128)<0)
	{
		ERR_MSG("listen");
	}
	printf("listen success\n");
 
	//存储客户端地址信息
	struct sockaddr_in cin;
	socklen_t addrlen=sizeof(cin);
 
	//定义事件结构体
	struct epoll_event event;
	//定义存放就绪事件描述符的数组
	struct epoll_event events[20];
 
	//创建红黑树根节点
	epfd = epoll_create(1);
	if(epfd<0)
	{
		ERR_MSG("epoll_create");
	}
	printf("成功创建红黑树根节点\n");
 
	//添加要检测的事件描述符
	event.events=EPOLLIN;
	event.data.fd=sfd;
	if(epoll_ctl(epfd,EPOLL_CTL_ADD,sfd,&event)<0)
	{
		ERR_MSG("epoll_ctl");
	}
	printf("成功将sfd事件描述符挂载到红黑树上\n");
 
 
	struct message buf;
	char msg[sizeof(buf)]="";
	int newfd=-1;
	while(1)
	{
		memset(&buf,0,sizeof(buf));	
		int ret=epoll_wait(epfd,events,20,-1);
		for(int i=0;i<ret;i++)
		{
			if(events[i].data.fd == sfd)
			{
				//获取连接成功后的新套接字
				newfd=accept(sfd,(struct sockaddr*)&cin,&addrlen);
				if(newfd<0)
				{
					ERR_MSG("accept");
				}
				printf("[%s : %d] newfd=%d 客户端连接成功\n", \
						inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), newfd);
 
				//添加要检测的事件描述符
				event.events=EPOLLIN;
				event.data.fd=newfd;
				if(epoll_ctl(epfd,EPOLL_CTL_ADD,newfd,&event)<0)
				{
					ERR_MSG("epoll_ctl");
				}
				printf("成功将newfd:%d事件描述符挂载到红黑树上\n",newfd);
			}
			else
			{
				int cfd=events[i].data.fd;
				int len=read(cfd,msg,sizeof(msg));
				memcpy(&buf,msg,sizeof(msg));
				if(len<=0)
				{
					close(cfd);
					epoll_ctl(epfd,EPOLL_CTL_DEL,cfd,NULL);
				}
				char c=buf.head[0];
				switch(c)
				{
				case '1':
					//1.查询图书信息
					search(cfd,buf);
					break;
				case '2':
					//2.添加图书
					add_book(cfd,buf);
					break;
				case '3':
					//3.更改图书信息
					update(cfd,buf);
					break;
				case '4':
					//4.删除图书
					delete(cfd,buf);
					break;
				case '5':
					//5.查阅借阅记录
					search_history(cfd);
					break;
				case '6':
					//6.退出	
					epoll_ctl(epfd,EPOLL_CTL_DEL,cfd,NULL);
					close(cfd);
					printf("成功退出\n");
					break;
				case '7':
					//7.借阅书籍
					borrow_books(cfd,buf);
					break;
				case '8':
					//8.归还书籍
					return_books(cfd,buf);
					break;
				case '9':
					//判断是管理员还是普通用户
					determine_member(cfd,buf);
					break;
				}
			}
		}
	} 
 
	//关闭文件描述符
	if(close(sfd) < 0)
	{
		ERR_MSG("close");
		return -1;
	}
	return 0;
}
//打开数据库,并创建人员信息表,图书信息表,借阅信息表
int create_table(sqlite3* db_books)
{
	//创建一个人员信息表格(用于判断是否是管理员id--管理员:y,普通用户:n)
	char sql[128] = "create table if not exists members (id char,name char,password char)";
	char* errmsg = NULL;
	if(sqlite3_exec(db_books,sql,NULL,NULL,&errmsg) != SQLITE_OK)
	{
		fprintf(stderr,"__%d__ sqlite3_exec:%s\n",__LINE__,errmsg);
		return -1;
	}
	//创建一个图书信息表格(书名,作者,个数)
	bzero(sql,sizeof(sql));
	strcpy(sql, "create table if not exists books (title char,author char,number char)");
	if(sqlite3_exec(db_books,sql,NULL,NULL,&errmsg) != SQLITE_OK)
	{
		fprintf(stderr,"__%d__ sqlite3_exec:%s\n",__LINE__,errmsg);
		return -1;
	}
	//创建一个借阅信息表格(书名,借书人,状态0-归还,1-借阅)
	bzero(sql,sizeof(sql));
	strcpy(sql, "create table if not exists history (title char,name char,state char)");
	if(sqlite3_exec(db_books,sql,NULL,NULL,&errmsg) != SQLITE_OK)
	{
		fprintf(stderr,"__%d__ sqlite3_exec:%s\n",__LINE__,errmsg);
		return -1;
	}

}

//判断是管理员还是普通用户
int determine_member(int cfd,struct message cli_buf)
{
	char name[128]="";
	char password[128]="";
	bzero(name,sizeof(name));
	bzero(password,sizeof(password));
	sprintf(name,"%s",cli_buf.name);
	sprintf(password,"%s",cli_buf.msg);
	struct message buf;	
	memset(&buf,0,sizeof(buf));

	char **results=NULL;
    int rows, cols;	
	char* errmsg=NULL;
	//查询用户登录是否正确,并且是否是管理员
	char sql[256]="";
	bzero(sql,sizeof(sql));
	snprintf(sql, sizeof(sql), "SELECT id FROM members WHERE name='%s' AND password='%s';", name, password);
	if(sqlite3_get_table(db_books,sql,&results,&rows,&cols,&errmsg)!=SQLITE_OK)
	{
		fprintf(stderr, "__%d__ sqlite3_get_table:%s\n", __LINE__, errmsg);
        return -1;
	}
	ssize_t res=0;
	if(rows>0)
	{
		if(strcmp((char*)results[1],"1")==0)
		{
			strcpy(buf.head,"1");
			res=write(cfd,&buf,sizeof(buf));
		}	
		else
		{
			strcpy(buf.head,"2");
			res=write(cfd,&buf,sizeof(buf));
		}
	}
	if(res<0)
	{
		printf("发送数据失败\n");
	}
	else{
		printf("发送数据成功\n");
	}
	return 0;
}	

//1.查询图书信息
int search(int cfd,struct message cli_buf)
{
	char title[32]="";
	bzero(title,sizeof(title));
	sprintf(title,"%s",cli_buf.msg);
	struct message buf;
	memset(&buf,0,sizeof(buf));

	char **results=NULL;
    int rows, cols;	
	char* errmsg=NULL;
	//查询图书信息
	char sql[256]="";
	snprintf(sql, sizeof(sql), "SELECT * FROM books WHERE title='%s'", title);
	if(sqlite3_get_table(db_books,sql,&results,&rows,&cols,&errmsg)!=SQLITE_OK)
	{
		fprintf(stderr, "__%d__ sqlite3_get_table:%s\n", __LINE__, errmsg);
        return -1;
	}
	printf("%s  %s  %s\n",results[3],results[4],results[5]);
	ssize_t res=0;
	if(rows>0)
	{
		if(strcmp((char*)results[3],title)==0)
		{
			strcpy(buf.head,results[3]);
			strcpy(buf.name,results[4]);
			strcpy(buf.msg,results[5]);
			res=write(cfd,&buf,sizeof(buf));
		}	
		else
		{
			strcpy(buf.msg,"没有相关的书名,请重新输入");
			res=write(cfd,&buf,sizeof(buf));
		}
	}
	if(res<0)
	{
		printf("发送数据失败\n");
	}
	else{

		printf("发送数据成功\n");
	}
	
	return 0;

}

//2.添加图书
int add_book(int cfd,struct message cli_buf)
{
	struct message buf;
	memset(&buf,0,sizeof(buf));	
	char title[32]="";
	sprintf(title,"%s",cli_buf.head+1);
	char* errmsg=NULL;

	//查询图书信息
	char sql[256]="";
	bzero(sql,sizeof(sql));
	snprintf(sql, sizeof(sql), "INSERT INTO books ('title','author','number') values (\"%s\",\"%s\",\"%s\")",title,cli_buf.name,cli_buf.msg);
	if(sqlite3_exec(db_books,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
	{
		fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__, errmsg);
        return -1;
	}
	strcpy(buf.msg,"insert success");
	write(cfd,&buf,sizeof(buf));
	printf("插入%s成功\n",cli_buf.head);
	return 0;

}

//3.更改图书信息
int update(int cfd,struct message cli_buf)
{
	struct message buf;
	memset(&buf,0,sizeof(buf));	
	char title[12]="";
	sprintf(title,"%s",cli_buf.head+1);
	char* errmsg=NULL;
	char **results=NULL;
    int rows, cols;	

	//查询图书信息
	char sql[256]="";
	bzero(sql,sizeof(sql));
	snprintf(sql, sizeof(sql), "update books set author=\"%s\",number=\"%s\" where title=\"%s\";",cli_buf.name,cli_buf.msg,title);
	if(sqlite3_get_table(db_books,sql,&results,&rows,&cols,&errmsg)!=SQLITE_OK)
	{
		fprintf(stderr, "__%d__ sqlite3_get_table:%s\n", __LINE__, errmsg);
        return -1;
	}
	if(rows>0)
	{
		strcpy(buf.msg,"update success");
		write(cfd,&buf,sizeof(buf));
		printf("修改%s信息成功\n",title);
	}
	else if(rows<0)
	{
		strcpy(buf.msg,"update failed");
		write(cfd,&buf,sizeof(buf));
		printf("没有%s的书籍,删除失败\n",title);
	}
	return 0;
}

//4.删除图书
int delete(int cfd,struct message cli_buf)
{
	struct message buf;
	memset(&buf,0,sizeof(buf));	
	char title[12]="";
	sprintf(title,"%s",cli_buf.head+1);
	char* errmsg=NULL;
	char **results=NULL;
    int rows, cols;	

	//删除图书
	char sql[256]="";
	snprintf(sql, sizeof(sql), "delete from books where title='%s'",title);
	if(sqlite3_get_table(db_books,sql,&results,&rows,&cols,&errmsg)!=SQLITE_OK)
	{
		fprintf(stderr, "__%d__ sqlite3_get_table:%s\n", __LINE__, errmsg);
        return -1;
	}
	if(rows>0)
	{
		strcpy(buf.msg,"delete success");
		write(cfd,&buf,sizeof(buf));
		printf("删除%s信息成功\n",title);
	}
	else
	{
		strcpy(buf.msg,"delete failed");
		write(cfd,&buf,sizeof(buf));
		printf("没有%s的书籍,删除失败\n",title);
	}
	return 0;

}

//5.查阅借阅记录
int search_history(int cfd)
{
	char sql[128]="";
	char **results=NULL;
	int rows,cols;
	char *errmsg=NULL;
	struct message buf;
	bzero(sql,sizeof(sql));
	sprintf(sql,"select *from history");
	if(sqlite3_get_table(db_books,sql,&results,&rows,&cols,&errmsg)!=SQLITE_OK)
	{
		fprintf(stderr, "__%d__ sqlite3_get_table:%s\n", __LINE__, errmsg);
        return -1;
	}	
	if(rows>0)
	for(int i=3;i<(rows*cols);i++)
	{
		strcpy(buf.msg,results[i]);
	}
	else
	{
		strcpy(buf.msg,"没有借阅信息");
	}
	write(cfd,&buf,sizeof(buf));
	printf("成功查阅借阅记录\n");

	return 0;

}
//7.借阅书籍
int borrow_books(int cfd,struct message cli_buf)
{
	struct message buf;
	memset(&buf,0,sizeof(buf));	
	char book_name[32]="";
	bzero(book_name,sizeof(book_name));
	strcpy(book_name,cli_buf.head+1);
	char **results=NULL;
    int rows=0, cols=0;	
	char* errmsg=NULL;
	//借阅书籍
	char sql[256]="";
	snprintf(sql, sizeof(sql), "select number from books where title=\"%s\";",book_name);
	if(sqlite3_get_table(db_books,sql,&results,&rows,&cols,&errmsg)!=SQLITE_OK)
	{
		fprintf(stderr, "__%d__ sqlite3_get_table:%s\n", __LINE__, errmsg);
        return -1;

	}
	if(rows>0)
	{
		//运行到这,说明有这本书,判断输出个数,对id进行操作
		if(strcmp(results[5],"0")==0)
		{
			//查到有此书,但是书的个数为0不能被借阅
			strcpy(buf.msg,"已全部被借阅");	
		}
		else
		{
			//可以被借阅,书的个数-1
			bzero(sql,sizeof(sql));
			snprintf(sql,sizeof(sql),"update books set number=\"%s\" where title=\"%s\";",results[5]-1,book_name);
			if(sqlite3_get_table(db_books,sql,&results,&rows,&cols,&errmsg)!=SQLITE_OK)
			{
				fprintf(stderr, "__%d__ sqlite3_get_table:%s\n", __LINE__, errmsg);
    	  	 	return -1;
			}
		
			//添加记录到历史记录表中
			bzero(sql,sizeof(sql));
			char c[5]="1";
			snprintf(sql,sizeof(sql),"insert into history (title,name,state) values (\"%s\",\"%s\",\"%s\")",book_name,cli_buf.name,c);
			if(sqlite3_exec(db_books,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
			{
				fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__, errmsg);
      			  return -1;
			}
			printf("成功添加借阅记录\n");
			strcpy(buf.msg,"borrow success");	
			printf("成功借阅%s\n",book_name);

		}
	}
	else if(rows<0)
	{
		strcpy(buf.msg,"delete failed");
		printf("没有%s的书籍,借阅失败\n",book_name);
	}
	write(cfd,&buf,sizeof(buf));
	return 0;

}

//8.归还书籍
int return_books(int cfd,struct message cli_buf)
{
	struct message buf;
	memset(&buf,0,sizeof(buf));	
	char title[32]="";
	bzero(title,sizeof(title));
	sprintf(title,"%s",cli_buf.msg);
	char* errmsg=NULL;
	char **results=NULL;
    int rows, cols;	

	//归还书籍
	char sql[256]="";
	bzero(sql,sizeof(sql));
	snprintf(sql, sizeof(sql), "select number from books where title='%s'",title);
	if(sqlite3_get_table(db_books,sql,&results,&rows,&cols,&errmsg)!=SQLITE_OK)
	{
		fprintf(stderr, "__%d__ sqlite3_get_table:%s\n", __LINE__, errmsg);
        return -1;
	}
	if(rows>0)
	{
			//可以归还,书的个数+1
			bzero(sql,sizeof(sql));
			snprintf(sql,sizeof(sql),"update books set number=\"%s\" where title=\"%s\"",results[5]+1,title);
			if(sqlite3_get_table(db_books,sql,&results,&rows,&cols,&errmsg)!=SQLITE_OK)
			{
				fprintf(stderr, "__%d__ sqlite3_get_table:%s\n", __LINE__, errmsg);
    	  	 	return -1;
			}
			//修改借阅记录的状态,显示已归还
			bzero(sql,sizeof(sql));
			snprintf(sql,sizeof(sql),"update history set state=\"%s\" where title='%s'","0",title);
			if(sqlite3_get_table(db_books,sql,&results,&rows,&cols,&errmsg)!=SQLITE_OK)
			{
				fprintf(stderr, "__%d__ sqlite3_get_table:%s\n", __LINE__, errmsg);
    	  	 	return -1;
			}

			strcpy(buf.msg,"return success");
			printf("成功归还图书\n");
	}
	else if(rows==0)
	{
		strcpy(buf.msg,"delete failed");
		printf("没有%s的书籍,归还失败\n",title);
	}
	write(cfd,&buf,sizeof(buf));
	return 0;

}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值