线上宠物领养系统

实现功能

客户端:客户可以查询数据库的宠物信息并根据查询的宠物信息选择自己喜欢的宠物进行领养。
服务器:服务器实现了对管理员相关信息的保存,管理员必须输入正确的用户名和密码才能对数据库信息进行增删改查等操作。服务器也可以直接对数据库信息进行查询。服务器进入默认模式后,就可以接收客户端的链接请求,并根据客户端的请求信息对数据库进行相应的操作

用到的关键技术

客户端与服务器通信时,使用的是IO多路服用技术进行通信,实现了一对多的通信方式。
服务器端对数据库进行增删改查操作,并利用文件管理的方式将管理员信息进行保存。

流程图

在这里插入图片描述

代码实现

服务器代码

主函数:

#include "net.h"


int main(int argc,char *argv[])
{
	User User1;
	//创建数据库
	sqlite3 *db;

	int op=0;
	while(1)
	{
		system("clear");
		printf("<<<<<<<<<欢迎进入宠物领养店>>>>>>>>>>\n");
		printf("1\t\t以管理员方式对数据库进行操作\n");
		printf("2\t\t展示宠物信息\n");
		printf("3\t\t默认模式\n");	
		printf("4\t\t退出\n");
		printf("请输入你的选择\n");
		scanf("%d",&op);
		switch(op)
		{
			case 1:
				{
					//实现用户的注册和登陆,并能够实现对数据库的增删改查
					user_registers_login_func(User1,db);
					break;
				}
			case 2:
				{
					//展示宠物信息	
					display(db);
					break;
				}
			case 3:
				{
					//默认模式,就是将服务器打开,系统开始接收客户端发来的的领养宠物的操作
					communication_func(argc,argv,db);
					break;
				}
			case 4:
				{
					//退出
					exit(0);
				}
		}
	}
	return 0;
}

函数定义

#ifndef _NET_H
#define _NET_H
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sqlite3.h>
//定义宠物的信息的结构体
typedef struct pot
{
	int ID;
    char nature[20];//宠物的属性
    char name[20];//名字
    char color[20];//颜色
    float age;//年龄
    float weight;//体重
}Pot;

//第一管理员信息的结构体
typedef struct The_users   //typedef 可以定义结构体别名
{
    char id[11]; //账号 
    char pwd[20]; //密码 
}User;

void Exit(void);  //退出函数
void registers(User User1); //用户注册
void login(User User1,sqlite3 *db);  //登录账号
int user_registers_login_func(User User1,sqlite3 *db);//实现用户的注册和登陆,并能够实现对数据库的增删改查
void analysis(char buf[],char username[],char passward[]);//解析字符串,对用户名和密码进行解析
void db_func(sqlite3 *db);//对数据库进行增删改查
void menu();//打印菜单
int insert(sqlite3 * db);//插入数据到数据库中
int callback(void *Notuserd,int argc,char *argv[],char *colName[]);//回调函数,在数据库中查找数据时,数据库返回的数据。
int Select(sqlite3 *db);//查看数据库值中的信息
int Delete(sqlite3 *db);//删除数据库中的信息
int Update(sqlite3 *db);//修改数据库中的数据
int Drop(sqlite3 *db);//删除数据库中创建的表
void display(sqlite3 *db);//展示宠物信息
int tcp_server(char * ip,int port);//编写一子函数,实现tcp的服务器端
int communication_func(int argc,char *argv[],sqlite3 *db);//实现服务器和客户端之间的通信
int tcp_com(int newfd);//实现和客户端通信

#endif

函数实现

#include "net.h"

//函数功能:实现用户的注册,将用户的信息保存到文件中
//参数:用户名
//返回值:void
void registers(User User1)  //用户注册
{
	//打开文件,将用户信息保存到文件中
	int fw=open("Message.txt",O_WRONLY | O_CREAT,0666);
	if(fw<0)
	{
		perror("open err");
		return ;
	}
	//定义用户的信息
	printf("请输入用户的账号和密码\n");
	scanf("%s%s",User1.id,User1.pwd);
	char buf[50]={0};
	printf("你输入的姓名和密码为\n");
	sprintf(buf,"username=%s&passward=%s",User1.id,User1.pwd);
	//将输入的用户信息和密码写入到文件中
	int ret = write(fw,buf,sizeof(buf));
	if(ret<0)
	{
		perror("fwrite err");
		return ;
	}
	close(fw);
	printf("用户信息输入成功\n");
}

//函数功能:解析字符串,对用户名和密码进行解析
//参数1:buf,文件中宝保存的用于名和密码的字符串
//参数2:username,解析出来的用户名
//参数3:password,解析出来的密码
//返回值:void
void analysis(char buf[],char username[],char passward[])
{
	int i=0;
	int j=0;
	int q=0;
	while(buf[i] != '\0')
	{
		if(buf[i] == '=')
		{
			break;
		}
		i++;
	}
	if(buf[i]!='=')
	{
		return ;
	}

	i++;
	while(buf[i+j] != '\0')
	{
		if(buf[i+j] == '&')
		{
			break;
		}
		username[j]=buf[i+j];
		j++;
	}
	username[j]='\0';
	if(buf[i+j] != '&')
	{
		return ;
	}
	//找到第二个等号
	while(buf[i+j+q] != '\0')
	{
		if(buf[i+j+q] == '=')
		{
			break;
		}
		q++;
	}
	if(buf[i+j+q] != '=')
		return ;
	i++;
	int k=0;
	while(buf[i+j+q+k] != '\0')
	{
		passward[k]=buf[i+j+q+k];
		k++;
	}
	passward[k]='\0';
}



//函数功能:登陆,用户先输入用户姓名和密码,然后将文件信息中的用户名和密码与输入信息作比较,不一致则登陆成功,
//一致则登陆失败,请重新登陆
//参数1:用户
//参数2:数据库
//返回值:void
void login(User User1,sqlite3 *db)
{
	printf("请输入你的用户名和和密码\n");
	scanf("%s%s",User1.id,User1.pwd);

	//打开文件
	int fr=open("Message.txt",O_RDONLY,0666);
	if(fr<0)
	{
		perror("open err");
		return ;
	}
	//读文件内容
	char buf[50]={0};
	int i=0;

	while(1)
	{
		int rd_count = read(fr,buf,sizeof(buf));
		if(0 == rd_count)
		{
			printf("倒入信息完毕\n");
			break;
		}
		else if(rd_count<0)
		{
			printf("倒入失败\n");
			return ;
		}
		else 
		{
			printf("%s\n",buf);
		}
	}
	//关闭文件
	close(fr);
	//解析文件数据
	char username[20];
	char passward[20];
	analysis(buf,username,passward);
	while(1)
	{
		//与输入信息作比较,一样则登陆成功,否则失败
		if((strcmp(username,User1.id)==0) && (strcmp(passward,User1.pwd)==0))
		{
			printf("登陆成功\n");
			printf("进入主界面\n");
			//管理员对数据库进行操作
			db_func(db);
			break;
		}
		else
		{
			printf("登陆失败,请重新输入\n");
			break;
		}
	}
}
//函数功能:退出登陆界面
//参数:void
返回值:void
void Exit(void)
{
	system("clear");
	printf("\n\n\n           ^*^感谢使用,祝您生活愉快!\n\n\n\n\n\n\n\n\n");
	return ;
}

//函数功能:用户的注册,登陆函数的实现
//参数1:用户名
//参数2:数据库
//返回值:成功返回0,失败返回-1
int user_registers_login_func(User User1,sqlite3 *db)
{
	int n;
	char buf[20]={0};
	do
	{
		system("clear");

		if(strncmp(buf,"quit",4)==0)
		{
			break;
		}
		printf("\n				             $登录界面$\n");
		printf("\n      1.用户注册           2.用户登录         3.退出程序\n");
		printf("\n^*^请选择:");

		scanf("%d",&n);
		switch(n)
		{
			case 1:
				registers(User1);
				break;
			case 2:
				login(User1,db);
				break;
			case 3:
				Exit();
				strcpy(buf,"quit");

			default:
				printf("#输入有误,请重新输入\n#");

				system("clear");
		}
	}while(1);
	return 0;
}


//函数功能:打印菜单
//参数:无
//返回值:无
void menu()
{
	printf("insert\t\t1\n");
	printf("selete\t\t2\n");
	printf("delete\t\t3\n");
	printf("update\t\t4\n");
	printf("销毁表\t\t5\n");
	printf("退出表\t-1\n");
	printf("请输入你的选择\n");
}

//函数功能:插入数据到数据库中
//参数:数据库
//返回值:成功返回0,失败返回-1
int insert(sqlite3 * db)
{
	//定义一个宠物的信息
	Pot Pot1;
	printf("请输入宠物的编号,名字,属性,颜色,年龄,体重\n");
	scanf("%d%s%s%s%f%f",&Pot1.ID,Pot1.name,Pot1.nature,Pot1.color,&Pot1.age,&Pot1.weight);
	char sql[100]={0};
	sprintf(sql,"insert into Pot values(%d,'%s','%s','%s',%.1f,%.1f)",Pot1.ID,Pot1.name,Pot1.nature,Pot1.color,Pot1.age,Pot1.weight);
	printf("sql=%s\n",sql);


	int rc=0;
	rc=sqlite3_exec(db,sql,NULL,NULL,NULL);
	if(rc != SQLITE_OK)
	{
		perror("insert err");
		return -1;
	}
	printf("insert ok\n");
	return 0;
}

//函数功能:回调函数,在数据库中查找数据时,数据库返回的数据。
//参数1:sqlite3_exec的第四个参数
//参数2:个数
//参数3:列名
//参数4:具体的名字
//返回值:成功返回0.失败返回-1
int callback(void *Notuserd,int argc,char *argv[],char *colName[])
{
	int i=0;

	for(i=0;i<argc;i++)
	{
		printf("%s ",argv[i]);
	}

	printf("\n");
	return 0;
}


//函数功能:查看数据库值中的信息
//参数1:sqlite3 *db
//返回值:成功返回0,失败返回-1
int Select(sqlite3 *db)
{
	char sql[100]={0};
	sprintf(sql,"select * from Pot");
	int rc;

	//参数3:函数的指针回调函数
	//参数4:给回调函数的参数
	//参数5:错误信息
	rc=sqlite3_exec(db,sql,callback,NULL,NULL);
	if(rc != SQLITE_OK)
	{
		perror("select err");
		return -1;
	}
	printf("select ok\n");
	return 0;
}


//函数功能:删除数据库中的信息
//参数:sqlite3 *db
//返回值:成功返回0,失败返回-1
int Delete(sqlite3 *db)
{
	//删除学生的信息
	printf("请输入要删除宠物的编号\n");
	int ID;
	scanf("%d",&ID);
	char sql[100]={0};
	sprintf(sql,"delete from Pot where ID = %d",ID);
	printf("sql=%s\n",sql);


	int rc=0;
	rc=sqlite3_exec(db,sql,NULL,NULL,NULL);
	if(rc != SQLITE_OK)
	{
		perror("delete err\n");
		return -1;
	}
	printf("delete ok\n");

	return 0;
}


//函数功能:修改数据库中的数据
//参数:sqlite3 *db
//返回值:成功返回0;失败返回-1
int Update(sqlite3 *db)
{
	//要修改的宠物的信息
	printf("请输入要修改的宠物的体重和要修改的姓名\n");
	float weight=0;
	char name[20]={0};
	scanf("%f%s",&weight,name);

	char sql[100]={0};
	sprintf(sql,"update Pot set weight = %f where name = '%s'",weight,name);
	printf("sql=%s\n",sql);

	int rc=0;
	rc=sqlite3_exec(db,sql,NULL,NULL,NULL);
	if(rc != SQLITE_OK)
	{
		perror("update err\n");
		return -1;
	}
	printf("update ok\n");

	return 0;
}

//函数功能:删除数据库中创建的表
//参数:sqlite3 *db
//成功返回0,失败返回-1
int Drop(sqlite3 *db)
{
	char sql[100]={0};
	sprintf(sql,"drop table Pot");
	printf("%s\n",sql);

	int rc=0;
	rc=sqlite3_exec(db,sql,NULL,NULL,NULL);
	if(rc != SQLITE_OK)
	{
		perror("drop err\n");
		return -1;
	}
	printf("drop ok\n");
	return 0;
}


//函数功能:数据库的操作
//参数:数据库
//返回值:void
void db_func(sqlite3 *db)
{
	int rc;//定义一个宠物的信息
	char *zErrMsg=0;
	rc=sqlite3_open("test.db",&db);

	//创建一张表
	if(rc)
	{
		printf("数据库打开失败\n");
		return ;
	}
	printf("打开成功\n");

	//拼好sql语句
	char sql[200]={0};
	sprintf(sql,"create table Pot (ID int primary key not null,name text,nature text,color text,age real,weight real)");
	printf("%s\n",sql);

	//参数1:sqlite3
	//参数2:char *sql语句
	//参数3:参数4:NULL
	//参数5:将错误信息显示
	rc=sqlite3_exec(db,sql,NULL,NULL,NULL);

	if(rc == SQLITE_OK)
	{
		printf("table create OK\n");
	}
	int op=0;
	while(1)
	{
		menu();
		scanf("%d",&op);
		if(op == -1)
		{
			break;
		}
		switch(op)
		{
			case 1:
				insert(db);
				break;
			case 2:
				Select(db);
				break;
			case 3:
				Delete(db);
				break;
			case 4:
				Update(db);
				break;
			case 5:
				Drop(db);
				break;
		}
	}
	//关闭数据库
	sqlite3_close(db);
}

//函数功能:展示所有宠物信息
//参数:sqlite3 *db
//返回值:无
void display(sqlite3 *db)
{
	int rc;
	rc=sqlite3_open("test.db",&db);
	//创建一张表
	if(rc)
	{
		printf("数据库打开失败\n");
		return ;
	}
	printf("打开成功\n");
	Select(db);
	printf("展示完成,是否退出\n");
	printf("退出请输入“quit”\n");
	char buf[20]={0};
	scanf("%s",buf);
	if(strncmp(buf,"quit",4)==0)
	{
		return ;
	}
}



//函数功能:编写一子函数,实现tcp的服务器端
//参数1:自己的IP地址   
//参数2:自己的PORT号
//返回值:成功监听的socket对象,失败返回-1
int tcp_server(char * ip,int port)
{

	//1.创建socket对象            socket()
	//2.设置自己的IP地址和端口号  struct sockaddr_in
	//3.绑定自己的IP地址和端口号  bind()
	//4.监听该socket对象          listen()

	//1.创建TCP socket
	int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
	if(0>socket_fd)
	{
		perror("create socket error");
		return -1;
	}
	printf("socket  ok\n");

	//2.设置自己的指定端口及ip地址
	struct sockaddr_in server;
	memset(&server,'\0',sizeof(server));

	server.sin_family = AF_INET;       //协议
	server.sin_port = htons(port);  //将主机字节序转换成网络字节序
	//端口号  "8888"  -->atoi("8888")  8888
	server.sin_addr.s_addr = inet_addr(ip);//将主机字节序转换成网络字节序
	//INADDR_ANY OS自动获取的是谁就用谁 //inet_addr("192.168.2.112") 将其转换成网络字节序
	//3.绑定自己的IP地址和端口号
	if(bind(socket_fd,(struct sockaddr *)&server,sizeof(server))<0)
	{
		perror("bind error");
		return -1;
	}
	printf("bind ok\n");

	//4.监听是否有人连接
	if(listen(socket_fd,5)<0)
	{
		perror("listen error");
		return -1;
	}
	printf("listen ok\n");
	return socket_fd;

}

//函数功能:实现和客户端通信
//参数1:连接好的文件描述符
//返回值:客户端断开连接返回-1,否则返回0
int tcp_com(int newfd)
{
	//4.服务器连接成功之后实现的具体操作使用的是接受连接之后的新的socket对象
	char buf[256] = {'\0'};

	while(1){
		memset(buf,'\0',sizeof(buf));
		recv(newfd,buf,sizeof(buf),0);//tcpsocke中提供专门接受的函数
		if(strncmp(buf,"quit",4)==0)
		{
			return -1;
		}
		printf("buf=%s\n",buf);
		//recv(newfd,buf,sizeof(buf),0);//tcpsocke中提供专门接受的函数
		//printf("buf=%s\n",buf);
	}
	return 0;
}

//函数功能:服务器不通过登陆直接查看数据库中的信息时用到的回调函数
//参数1:sqlite3_exec的第四个参数
//参数2:个数
//参数3:列名
//参数4:具体的名字
//返回值:成功返回0,失败返回-1
int callback_client(void *pNewfd,int argc,char *argv[],char *colName[])
{
	int i=0;
	int *pfd=(int *)pNewfd;
	int fd=*pfd;

	Pot pot1;
	pot1.ID=atoi(argv[0]);
	strcpy(pot1.name,argv[1]);
	strcpy(pot1.nature,argv[2]);
	strcpy(pot1.color,argv[3]);
	pot1.age=atof(argv[4]);
	pot1.weight=atof(argv[5]);

	//printf("%s %s %s %f %f\n",pot1.name,pot1.nature,pot1.color,pot1.age,pot1.weight);
	//printf("连接好的socket对象%d\n",fd);

	send(fd,&pot1,sizeof(pot1),0);
	//printf("\n");
	sleep(1);
	return 0;
}

//函数功能:不通过登陆直接查询数据库中的信息
//参数1:sqlite3 *db
//参数2:连接好的文件描述符
//返回值:成功返回0,失败返回-1
int Select_client(sqlite3 *db,int newfd)
{
	char sql[100]={0};
	int rc;
	rc=sqlite3_open("test.db",&db);

	sprintf(sql,"select * from Pot");

	//参数3:函数的指针回调函数
	//参数4:给回调函数的参数
	//参数5:错误信息
	rc=sqlite3_exec(db,sql,callback_client,&newfd,NULL);

	if(rc != SQLITE_OK)
	{
		perror("select_client err");
		return -1;
	}
	printf("select_client ok\n");
	sqlite3_close(db);
	return 0;
}

//函数功能:实现服务器和客户端之间的通信
//参数1:ip地址
//参数2:端口号
//参数3:数据库
//返回值:成功返回0,失败返回-1
int communication_func(int argc,char *argv[],sqlite3 *db)
{
	//1.入参判断
	if(argc < 3)
	{
		perror("参数有误\n");
		return -1;
	}
	//2.获得监听好的socket对象
	int listenfd=tcp_server(argv[1],atoi(argv[2]));
	//接收连接
	int newfd=0;//用来保存连接后的socket对象

	struct sockaddr_in client;
	int len=sizeof(client);

	//IO多路复用并法服务器
	//1.定义两个监控队列
	fd_set rdfs,temp;

	//2.清空监听队列
	FD_ZERO(&rdfs);
	FD_ZERO(&temp);


	//3.将监听套接子加入到监听列表中
	FD_SET(listenfd,&rdfs);
	int i=0;
	while(1)
	{
		//4.将rdfs复制给temp
		temp=rdfs;
		//5.select阻塞监控,监控的是temp
		if(select(FD_SETSIZE,&temp,NULL,NULL,NULL)<0)
		{
			perror("select error");
			return -1;
		}

		//FD_SETSIZE 1024
		//6.selete退出必然有文件描述符的状态发生了变化
		//7.遍历文件描述符
		for(i=0;i<FD_SETSIZE;i++)
		{
			if(FD_ISSET(i,&temp))
			{
				if(i==listenfd)
				{
					//有客户端连接
					newfd=accept(i,(struct sockaddr *)&client,&len);
					if(newfd<0)
					{
						perror("accept error");
						return -1;
					}
					printf("accept success\n");
					printf("client IP=%s PORT=%d\n",inet_ntoa(client.sin_addr),ntohs(client.sin_port));
					//8.将连接好的新的套接子加入到监控队列中
					FD_SET(newfd,&rdfs);
				}
				else//表示套接子有数据传过来
				{
					char buf[20]={0};

					int n=recv(i,buf,sizeof(buf),0);
					if(n==0)
					{
						break;
					}

					printf("buf=%s\n",buf);


					if(strncmp(buf,"quit",1)==0)
					{
						printf("socket %d\n",i);
						close(i);
						FD_CLR(i,&rdfs);//将套接子从监听队列中删除
						return 0;
					}
					else if(strncmp(buf,"select",6)==0)
					{
						//打开数据库,发送宠物信息给客户端展示
						//printf(".........................\n");
						Select_client(db,newfd);
						send(newfd,"quit",4,0);
						//display(db);
						break;						
					}
					else if(strncmp(buf,"buy",3)==0)
					{
						//如果接收到的是宠物的名字的话,查询数据库,根据数据库的名字删除该宠物
						//Select_client(db,newfd);
						//操作数据库
						int rc;
						rc=sqlite3_open("test.db",&db);

						int flag=0;
						int n=recv(i,&flag,sizeof(flag),0);
						printf("%d\n",flag);
						//sleep(3);
						char sql[100]={0};
						sprintf(sql,"delete from Pot where ID = %d",flag);
						printf("sql=%s\n",sql);


						rc=sqlite3_exec(db,sql,NULL,NULL,NULL);
						if(rc != SQLITE_OK)
						{
							perror("delete err\n");
							return -1;
						}

						printf("delete ok\n");
						Select(db);
						printf("客户已经购买成功\n");
						printf("是否退出?\n");
						printf("quit\t退出\n");

						char buf[20]={0};
						scanf("%s",buf);
						if(strncmp(buf,"quit",4)==0)
						{
							return 0;
						}
					}
				}
			}
		}
	}
	close(listenfd);
}

客户端

主函数

#include "net.h"



int main(int argc,char *argv[])
{
	char buf[20]={0};
	while(1)
	{
		system("clear");
		printf("<<<<<<<<<欢迎进入宠物领养店>>>>>>>>>>\n");
		printf("select\t\t展示宠物信息\n");
		printf("quit\t\t退出\n");
		printf("请输入你的选择\n");
		fgets(buf,sizeof(buf),stdin);

		if(strncmp(buf,"select",6)==0)
		{
			display_info(argc,argv);
		}
		else if(strncmp(buf,"quit",4)==0)
		{
			break;
		}
	}
	return 0;
}

函数声明

#ifndef __NET_H
#define __NET_H

#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sqlite3.h>
//定义宠物的信息的结构体
typedef struct pot
{
    int ID;
    char nature[20];//宠物的属性
    char name[20];//名字
    char color[20];//颜色
    float age;//年龄
    float weight;//体重
}Pot;

//定义管理员信息的结构体
typedef struct users   //typedef 可以定义结构体别名
{
    char id[11]; //账号 
    char pwd[20]; //密码 
}User;

int connect_Func(char *ip,int port);//与服务器进行连接的函数
int display_info(int argc,char *argv[]);//展示宠物信息,当和服务器进行连接成功后,客户端发送查询宠物信息,服务器就会将宠物信息发送给客户端

#endif

函数实现

#include "net.h"

//函数功能:与服务器进行连接的函数
//参数1:ip
//参数2:端口号:port
//返回值:成功返回连接处成功的socket对象,失败返回-1
int connect_Func(char *ip,int port)
{

	//创建套接子
	//设置对方的IP和端口号
	//请求连接
	//发送消息
	//关闭socket对象


	//创建套接子
	int tcp_socket=socket(AF_INET,SOCK_STREAM,0);
	if(tcp_socket<0)
	{
		perror("socket err");
		return -1;
	}
	//设置对方的IP和端口号

	//定义一个结构体并赋值
	struct sockaddr_in server;

	server.sin_family=AF_INET;//IPV4协议
	server.sin_port=htons(port);
	server.sin_addr.s_addr=inet_addr(ip);

	//请求连接
	if(connect(tcp_socket,(struct sockaddr *)&server,sizeof(server))<0)
	{
		perror("connect err");
		return -1;
	}
	printf("connect ok\n");
	return tcp_socket;
}




//函数功能:展示宠物信息,当和服务器进行连接成功后,客户端发送查询宠物信息,服务器就会将宠物信息发送给客户端
//后查询数据库,并将宠物信息发送给客户端
//参数1:ip
//参数2:端口号 
//返回值:成功返回0,失败返回的-1;

int display_info(int argc,char *argv[])
{
	//入参判断
	if(argc>3)
	{
		perror("参数有无");
		return -1;
	}
	//创建连接
	int tcp_socket=connect_Func(argv[1],atoi(argv[2]));
	//发送消息

	char buf[20]={0};
	memset(buf,0,sizeof(buf));
	printf("write:\n");
	strcpy(buf,"select");

	send(tcp_socket,buf,strlen(buf),0);//发送数据
	sleep(1);

	if(strncmp(buf,"select",6)==0)
	{
		Pot pot1;

		while(1)
		{
			int n=recv(tcp_socket,&pot1,sizeof(pot1),0);
			printf("n=%d\n",n);
			if(n<sizeof(pot1))
			{
				//询问客户是否要进行购买,输入buy进入购买连接
				printf("是否需要领养\n");
				printf("领养输入1,退出输入2\n");
				int flag;
				scanf("%d",&flag);
				if(flag==1)
				{
					//购买
					memset(buf,0,sizeof(buf));
					printf("write:\n");
					strcpy(buf,"buy");

					send(tcp_socket,buf,strlen(buf),0);//发送数据

					printf("请输入你想要领养的宠物的编号\n");
					int flag=0;

					//fgets(buf_name,sizeof(buf_name),stdin);
					scanf("%d",&flag);
					send(tcp_socket,&flag,sizeof(flag),0);
					//printf("%d\n",flag);
					printf("购买成功\n");
					printf("是否退出?\n");
					printf("quit\t退出\n");
					
					char buf[20]={0};
					scanf("%s",buf);
					if(strncmp(buf,"quit",4)==0)
					{
						break;
					}
				}
				else
				{
					break;
				}
			}
			printf("%d %s %s %s %.1f %.1f\n",pot1.ID,pot1.name,pot1.nature,pot1.color,pot1.age,pot1.weight);
		}
	}
	//关闭socket对象
	close(tcp_socket);
	return 0;
}

编译运行

编译
在这里插入图片描述
主界面
在这里插入图片描述

先对服务器端进行操作,先择1,以管理员方式对数据库进行操作
在这里插入图片描述

选择1,注册信息,输入用户名zhangsan和密码123456
在这里插入图片描述

再输入2,进行用户登录,输入刚刚输入的用户名和密码
在这里插入图片描述

登录成功显示登录成功。登录成功后开始对数据库进行增删改查
输入1,插入信息,将宠物信息输入数据库
在这里插入图片描述
插入成功后提示insert ok
输入2查询插入的信心是否插入成功
在这里插入图片描述
红色框中的数据即为插入的数据,插入成功
输入3可以删除数据库中的信息
在这里插入图片描述

输入3后再输入你要删除的宠物编号,成功则显示delete ok,也可以输入2查看是否删除成功
在这里插入图片描述
输入2后查看,未发现编号为9的宠物信息,说明删除成功。
输入4修改宠物信息,宠物信息的修改是根据宠物的名字修改宠物的体重:
在这里插入图片描述

修改后再次查看,宠物体重发生变化。
输入5是数据库中创建的表,由于后面要对数据库进行操作,在此不做演示。
输入-1,退出
在这里插入图片描述
退出到登录界面,输入3,退出登录界面
在这里插入图片描述
退出到主界面
输入2,展示数据库中所有宠物信息
在这里插入图片描述
展示完成后想退出,驶入quit即可退出
在这里插入图片描述
输入3进入默认模式,此时服务器可以接收客户端的链接
在这里插入图片描述
客户端输入select查询,即可链接数据库
在这里插入图片描述
链接成功后,服务器就会将查询数据库,并将数据库中的信息发送给客户端。客户端询问客户是否要领养宠物,领养输入1,退出输入2,此处选择领养,并将领养的宠物的编号发送给服务器
在这里插入图片描述

服务器收到领养宠物的编号后,将改编号的宠物从数据库中删除,并展示剩余的宠物信息,客户端即领养成功。
客户端选择退出,回到主界面
在这里插入图片描述
再次退出,退出程序。
在这里插入图片描述
服务器端退出,退出到主界面
在这里插入图片描述
再次选择退出,退出到主界面
在这里插入图片描述

以上就是此次宠物领养系统的所有代码和编译执行的全过程,适合刚开始学习C语言的朋友们学习,希望能对你们提供一些指导和帮助。该功能还有很多有缺陷的地方,还请各位大佬在评论区中提一提自己宝贵的意见,万分感谢。
  • 6
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哈哈吓

您的打赏是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值