C网络编程项目 图书借阅系统(一)

本文详细描述了一个图书借阅系统的开发,包括C语言编写的并发服务器,用户注册登录、书籍管理功能,如增删查改,以及使用TCP协议与SQLite3数据库的交互。重点介绍了服务器接受客户端请求、解析指令及数据库操作的过程。
摘要由CSDN通过智能技术生成

1、项目名称

图书借阅系统

2、项目需求

对于图书馆中的书籍信息的管理,可以增、删、改、查书籍的信息,完成借阅、归还书籍的要求。

3、项目功能

1、采用并发服务器,可以同时处理多个客户端的请求。
2、客户端先注册、登录账号
3、登陆成功后可以增加、删除、查看书的信息
4、查阅、归还书籍

4、开发平台:

开发环境:Linux操作系统
开发语言:C语言

5、需求分析:

1、服务器和客户端采用TCP通信协议
2、服务器采用IO多路复用的并发服务器
3、客户端发送一长串消息给服务器,服务器解析分出有用信息后,对Sqlite3数据库的数据操作
在这里插入图片描述
在这里插入图片描述

6、项目框架

服务器启动流程
Init_net 初始化网络
Socket
Bind
Listen
将需要监听的文件描述符加入相应的文件描述符集合
Accept 等待连接请求
Send/recv 成功连接后执行操作
Close 关闭服务器
客户端启动流程
Socket
Connect 发送连接请求,成功则表明已连接至服务器
Send、recv 发送操作请求
Close
服务器与客户端交互流程
在客户端成功连上服务器后。
服务器发送一级菜单
Menu
-----1登录-----
-----2注册-----
-----0退出-----
客户端收到菜单后,根据需求发送不同cmd
服务器根据不同cmd 执行不同的操作
当客户端发送注册命令后,服务器打开账号信息数据库,添加新的账号,密码。
当客户端发送登录命令后,服务器提示客户端输入账号密码,当接收到账号密码后,服务器端打开账号信息数据库,查找账号,返回密码信息,判断输入密码与返回的密码信息,相等则服务器返回成功登录,不等则返回密码错误,重新输入的字样。
在成功登录后,客户端即可以发送增删查改的请求,服务器接收后,根据请求对书籍信息数据库执行不同操作。

7、服务器搭建

#include "../../include/ser.h"

char buf[1024];
int main()
{
	int listenfd = init_net(8888);
	if(listenfd < 0)
	{
		puts("init net error.");
		return -1;
	}
	fd_set tempfds, readfds;
	FD_ZERO(&tempfds);	
	FD_ZERO(&readfds);

	FD_SET(listenfd, &readfds);

	while(1)
	{
		tempfds = readfds;
		int ret = select(FD_SETSIZE, &tempfds, NULL, NULL, NULL);
		if(ret > 0)
		{
			int i = 0;
			for(i = 3; i < FD_SETSIZE; i++)
			{
				if(FD_ISSET(i, &tempfds))
				{
					if(i == listenfd)
					{
						struct sockaddr_in mycli;
						int len = sizeof(mycli);
						int connfd = -1;
						connfd = accept(listenfd, (struct sockaddr *)&mycli, &len);
						if(connfd > 0)
						{
							int flags = fcntl(connfd, F_GETFL);
							fcntl(connfd, F_SETFL, flags | O_NONBLOCK);
							FD_SET(connfd, &readfds);
							puts("a client accept success.");
						}
					}
					else
					{
						memset(buf, 0, sizeof(buf));
						ret = recv(i, buf, sizeof(buf), 0);
						puts(buf);
						if(ret > 0)
						{
							char ID[20] = {0};
							char account[20] = {0};
							char passwd[20] = {0};
							char cmd[20] = {0};
							char status[20] = {0};
							char name[20];
							char address[20];
							memset(cmd,0,20);
							getCmd(cmd,buf);
							if(strcmp(cmd,"log") == 0)
							{
								memset(account,0,20);
								memset(passwd,0,20);
								getAccount(account, buf);
								getPasswd(passwd,buf);
								login(i,account,passwd);
							}
							if(strcmp(cmd, "reg") == 0)
							{
								memset(account,0,20);
								memset(passwd,0,20);
								getAccount(account, buf);
								getPasswd(passwd,buf);
								//puts("我要写入数据了");
								regin(i,account,passwd);
							}
							if(strcmp(cmd,"sek") == 0)
							{
								memset(ID,0,20);
								getID(ID,buf);
								ret = check_ID_exist(ID);
								if(ret == 0)
								{
									sek_book_info(i,ID);
								}
								else
								{
									send(i,"库中查无此id",50,0);
								}
							}
							if(strcmp(cmd,"add") == 0)
							{
								memset(ID,0,20);
								memset(status,0,20);
								memset(name,0,20);
								memset(address,0,20);
								getID(ID,buf);
								get_msg(buf,name,address,status);
								add_book_info(i,ID,name,address,status);
							}
							if(strcmp(cmd,"del") == 0)
							{
								memset(ID,0,20);
								getID(ID,buf);
								ret = check_ID_exist(ID);
								if(ret == 0)
								{
									del_book_info(i,ID);
								}
								else
								{	
									send(i,"库中查无此id",50,0);
								}
							}
							if(strcmp(cmd,"rev") == 0)
							{
								memset(ID,0,20);
								getID(ID,buf);
								memset(status,0,20);
								getstatus(status,buf);
								puts(ID);
								puts(status);
								ret = check_ID_exist(ID);
								if(ret == 0)
								{
									rev_book_info(i,ID,status);
								}
								else
								{
									send(i,"库中查无此id",50,0);
								}
							}
						}
						else if(ret == 0)
						{
							FD_CLR(i, &readfds);
							close(i);
							puts("a client exit.");
						}
						else
						{
							continue;
						}
					}
				}
			}
		}
	}	
	close(listenfd);
	return 0;
}
#include "../../include/ser.h"


char msg[255] = {0};
char buf[1024];
char success_buf[20] = "success";
char error_buf[20] = "error";


int init_net(unsigned short port)
{
	int serfd = -1;
	serfd = socket(AF_INET, SOCK_STREAM, 0);
	if(serfd < 0)
	{
		puts("socket error.");
		return -1;
	}

	puts("socket success.");

	struct sockaddr_in myser;
	memset(&myser, 0, sizeof(myser));
	myser.sin_family = AF_INET;
	myser.sin_port = htons(port);
	myser.sin_addr.s_addr = htonl(INADDR_ANY);

	int ret = bind(serfd, (struct sockaddr *)&myser, sizeof(myser));
	if(ret != 0)
	{
		puts("bind error.");
		close(serfd);
		return -1;
	}
	puts("bind success.");

	ret = listen(serfd, 5);
	if(ret != 0)
	{
		puts("listen error.");
		close(serfd);
		return -1;
	}
	int flags = fcntl(serfd, F_GETFL);
	fcntl(serfd, F_SETFL, flags | O_NONBLOCK);
	return serfd;
}
int getstatus(char *status,char *buf)
{
	if(NULL == status || NULL == buf)
	{
		puts("NULL pointer error");
		return ERROR;
	}
	memcpy(status,buf+11,20);
	return OK;
}
int getAccount(char *Account,char *login_buf)
{
	if(NULL == Account || NULL == login_buf)
	{
		puts("NULL pointer error");
		return ERROR;
	}
	memcpy(Account,login_buf+4,6);
	return OK;
}
int getID(char *ID,char *buf)
{
	if(NULL == ID || NULL == buf)
	{
		puts("NULL pointer error");
		return ERROR;
	}
	memcpy(ID,buf+4,6);
	return OK;
}
int getPasswd(char *Passwd,char *login_buf)
{
	if(NULL == Passwd || NULL == login_buf)
	{
		puts("NULL pointer error");
		return ERROR;
	}
	memcpy(Passwd,login_buf+11,6);
	return OK;
}
int getCmd(char *cmd,char *buf)
{
	if(NULL == cmd || NULL == buf)
	{
		puts("NULL pointer error");
		return ERROR;
	}
	memcpy(cmd,buf,3);
	return OK;
}
int login(int connfd,char *Account,char *Passwd)
{
	sqlite3 *pdb;
	char *errmsg = NULL;
	sqlite3_open("lib.db",&pdb);
	if(NULL == pdb)
	{
		puts("open db error.");
		return -1;
	}
	puts("open db success.");
	char data[100] = {0};
	char sql[255] = {0};
	sprintf(sql,"select Passwd from usr_info where Account = %s; ",Account);
	sqlite3_exec(pdb, sql, get_passwd, data, &errmsg);
	if(errmsg)
	{
		puts(errmsg);
		sqlite3_close(pdb);
		return -1;
	}
	if(strcmp(data,Passwd) == 0)
	{
		puts("验证成功");
		send(connfd,success_buf,50,0);
	}
	else
	{
		puts("未通过验证");
		send(connfd,error_buf,50,0);
	}
	sqlite3_close(pdb);
	return 0;
}
int regin(int connfd,char *Account,char *Passwd)
{
	sqlite3 *pdb;
	char *errmsg = NULL;
	sqlite3_open("lib.db",&pdb);
	if(NULL == pdb)
	{
		puts("open db error.");
		return -1;
	}
	puts("open db success.");
	char data[100] = {0};
	char sql[255] = {0};
	sprintf(sql,"INSERT INTO usr_info (Account,Passwd) VALUES(%s,%s);",Account,Passwd);
	puts(sql);
	if(sqlite3_exec(pdb, sql, NULL, 0, &errmsg) != SQLITE_OK)
	{
		printf("%s\n",errmsg);
	}
	else
	{
		puts("注册完成");
		send(connfd,"reg_success",50,0);
	}
	sqlite3_close(pdb);
	return 0;
}
int sek_book_info(int connfd,char *ID)
{
	sqlite3 *pdb;
	char ret_buf[255] = {0};
	char data[100];
	char *errmsg = NULL;
	sqlite3_open("lib.db",&pdb);
	if(NULL == pdb)
	{
		puts("open db error.");
		return -1;
	}
	puts("open db success.");
	char sql[255] = {0};
	sprintf(sql,"select * from book where ID = %s ;",ID);
	if(sqlite3_exec(pdb, sql, callback, NULL, &errmsg ) != SQLITE_OK)
	{
		printf("%s\n", errmsg);
		sqlite3_close(pdb);
		return -1;
	}
	else
	{
		printf("成功读取数据.\n");
		send(connfd,msg,sizeof(msg),0);
	}	
	sqlite3_close(pdb);
	return 0;
}
int callback(void *para, int f_num, char **f_value, char **f_name)
{
	int i = 0;
	memset(msg,0,sizeof(msg));
	for(i = 0; i < f_num; i++)
	{
		printf("%-11s ", f_value[i]);
		strcat(msg,f_value[i]);
	}
	printf("\n");
	return 0;
}
static int get_passwd(void *data,int argc,char **argv,char **column_name)
{
	if(NULL == data)
	{
		return ERROR;
	}
	if(argc == 1)
	{
		strcpy(data,argv[0]);
	}
	return OK;
}
int del_book_info(int connfd,char *ID)
{
	sqlite3 *pdb;
	char ret_buf[255] = {0};
	char data[100];
	char *errmsg = NULL;
	sqlite3_open("lib.db",&pdb);
	if(NULL == pdb)
	{
		puts("open db error.");
		return -1;
	}
	puts("open db success.");
	char sql[255] = {0};
	sprintf(sql,"delete from book where ID = %s ;",ID);
	if(sqlite3_exec(pdb, sql, NULL, 0, &errmsg) != SQLITE_OK)
	{
		printf("%s\n",errmsg);
	}
	else
	{
		puts("删除完成");
		sqlite3_close(pdb);
		send(connfd,"success",50,0);
	}
	return 0;	
}
int rev_book_info(int connfd,char *ID,char *status)
{
	sqlite3 *pdb;
	char ret_buf[255] = {0};
	char data[100];
	char *errmsg = NULL;
	sqlite3_open("lib.db",&pdb);
	if(NULL == pdb)
	{
		puts("open db error.");
		return -1;
	}
	puts("open db success.");
	char sql[255] = {0};
	sprintf(sql,"UPDATE book set STATUS = '%s' where ID = %s ;",status,ID);
	puts(sql);
	if(sqlite3_exec(pdb, sql, NULL, 0, &errmsg) != SQLITE_OK)
	{
		printf("%s\n",errmsg);
	}
	else
	{
		puts("修改完毕");
		send(connfd,"success",50,0);
	}
	sqlite3_close(pdb);
	return 0;	
}
int get_msg(char *buf,char *name,char *address,char *status)
{
	if(NULL == buf || NULL == name || NULL == address || NULL == status)
	{
		puts("入参错误");
		return ERROR;
	}
	char *temp = NULL;
	char *p = buf;
	p = p + 11;
	while(1)
	{
		if(':' == *p)
		{
			break;	
		}
		else
		{
			*name = *p;
			name += 1;
			p += 1;
		}
	}
	char *q = p+1;
	while(1)
	{
		if(':' == *q)
		{
			break;
		}
		else
		{
			*address = *q;
			address += 1;
			q += 1;
		}
	}
	strcpy(status,q+1);
	return 0;
}
int add_book_info(int connfd,char *ID,char *name,char *address,char *status)
{	
	if(NULL == ID || NULL == name || NULL == address || NULL == status)
	{
		puts("入参错误");
		return ERROR;
	}
	sqlite3 *pdb;
	char *errmsg = NULL;
	sqlite3_open("lib.db",&pdb);
	if(NULL == pdb)
	{
		puts("open db error.");
		return -1;
	}
	puts("open db success.");
	char data[100] = {0};
	char sql[255] = {0};
		memset(sql,0,sizeof(sql));
		sprintf(sql,"INSERT INTO book (ID,NAME,ADDRESS,STATUS) VALUES(%s,'%s','%s','%s');",ID,name,address,status);
		if(sqlite3_exec(pdb, sql, NULL, 0, &errmsg) != SQLITE_OK)
		{
			printf("%s\n",errmsg);
			return ERROR;
		}
	sqlite3_close(pdb);
	send(connfd,"success",50,0);
	return OK;
}
int check_ID_exist(char *ID)
{
	sqlite3 *pdb;
	char *errmsg = NULL;
	sqlite3_open("lib.db",&pdb);
	if(NULL == pdb)
	{
		puts("open db error.");
		return -1;
	}
	puts("open db success.");
	char data[100] = {0};
	char sql[255] = {0};
	sprintf(sql,"select ID from book where ID like %s ;",ID);
	sqlite3_exec(pdb, sql, get_passwd, data, &errmsg);
	if(errmsg)
	{
		puts(errmsg);
		sqlite3_close(pdb);
		return -1;
	}
	if(strcmp(data,ID) == 0)
	{
		sqlite3_close(pdb);
		return 0;
	}
	else
	{
		sqlite3_close(pdb);
		return -1;
	}
}
int check_Account_exist(char *Account)
{
	sqlite3 *pdb;
	char *errmsg = NULL;
	sqlite3_open("lib.db",&pdb);
	if(NULL == pdb)
	{
		puts("open db error.");
		return -1;
	}
	puts("open db success.");
	char data[100] = {0};
	char sql[255] = {0};
	sprintf(sql,"select Account from usr_info where Account like %s ;",Account);
	sqlite3_exec(pdb, sql, get_passwd, data, &errmsg);
	if(errmsg)
	{
		puts(errmsg);
		sqlite3_close(pdb);
		return -1;
	}
	if(strcmp(data,Account) == 0)
	{
		sqlite3_close(pdb);
		return 0;
	}
	else
	{
		sqlite3_close(pdb);
		return -1;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值