client.h
#ifndef _CLIENT_H_
#define _CLIENT_H_
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#define N 32
#define R 1 //user - register
#define L 2 //user - login
#define Q 3 //user - query
#define H 4 //user - history
#define D 5 //user - distroy
#define F 6 //user - retrieve_passwor
#define S 7 //goods - select
#define T 8
//定义通信双方的信息结构体
typedef struct messgae{
int type;
char name[16];
char passwd[64];
char number[12];
int price;
int num;
}MSG;
typedef struct {
char name[32];
char num[16];
char price[16];
}GOODS;
void do_register(int sockfd,MSG *msg);
void do_distroy(int sockfd,MSG *msg);
int do_select(int sockfd,MSG *msg,GOODS *good);
int do_login(int sockfd,MSG *msg);
int get_date(char *date);
int shopping(int sockfd,MSG *msg);
int do_retrieve_passwor(int sockfd,MSG *msg);
int do_history(int sockfd,MSG *msg);
int do_tuidan(int sockfd,MSG *msg);
#endif
client.c
#include "client.h"
void do_register(int sockfd,MSG *msg)
{
msg->type = R;
printf("请输入帐号:");
scanf("%s",msg->name);
getchar();
printf("请输入密码:");
scanf("%s",msg->passwd);
getchar();
printf("请输入手机号:");
scanf("%s",msg->number);
getchar();
if(send(sockfd,msg,sizeof(MSG),0) < 0)
{
printf("fail to send.\n");
return;
}
if(recv(sockfd,msg,sizeof(MSG),0) < 0)
{
printf("fail to recv.\n");
return ;
}
printf("%s\n",msg->passwd);
return;
}
void do_distroy(int sockfd,MSG *msg) //注销
{
msg->type = D;
printf("请输入帐号:");
scanf("%s",msg->name);
getchar();
printf("请输入密码:");
scanf("%s",msg->passwd);
if(send(sockfd,msg,sizeof(MSG),0) < 0)
{
printf("fail to send.\n");
return ;
}
if(recv(sockfd,msg,sizeof(MSG),0) < 0)
{
printf("fail to recv.\n");
return ;
}
if(strcmp(msg->passwd,"注销成功!")==0)
{
printf("注销成功!\n");
return ;
}
else
{
printf("%s\n",msg->passwd);
}
}
int do_select(int sockfd,MSG *msg,GOODS *good)
{
msg->type=S;
int i;
char buf[45];
if(send(sockfd,msg,sizeof(MSG),0)<0)
{
printf("fail to send\n");
return -1;
}
printf("\033[44;1m****************货物清单*****************\033[0m\n");
printf("****货物名称****货物数量****货物单价*****\n");
for(i = 0;i <= 6;i++)
{
bzero(buf,45);
recv(sockfd,buf,45,0);
printf("%s ****\n",buf);
}
printf("**1.购货**2.退货**3.查询**4.退出**5.返回*\n");
printf("\033[44;1m*****************************************\033[0m\n");
printf("Please choose:");
}
int do_login(int sockfd,MSG *msg)
{
msg->type = L;
printf("请输入帐号:");
scanf("%s",msg->name);
getchar();
printf("请输入密码:");
scanf("%s",msg->passwd);
if(send(sockfd,msg,sizeof(MSG),0) < 0)
{
printf("fail to send.\n");
return -1;
}
if(recv(sockfd,msg,sizeof(MSG),0) < 0)
{
printf("fail to recv.\n");
return -1;
}
if(strncmp(msg->passwd,"OK",2) == 0)
{
printf("登录成功!\n");
return 1;
}
else
{
printf("%s\n",msg->passwd);
}
return 0;
}
int shopping(int sockfd,MSG *msg)
{
msg->type = Q;
char goodname[32];
char date[64];
int price1,price;
int neednum,havenum;
printf("请输入你要购买的货物名称:");
scanf("%s",goodname);
strcpy(msg->passwd,goodname);
send(sockfd,msg,sizeof(MSG),0);
printf("send success : %s\n",goodname);
if(recv(sockfd,msg,sizeof(MSG),0) < 0)
{
printf("fail to recv!\n");
return -1;
}
havenum = msg->num;
printf("请输入购买数量:");
scanf("%d",&msg->num);
neednum = msg->num;
send(sockfd,msg,sizeof(MSG),0);
if(havenum <= 0)
{
printf("货物已售罄!\n");
return -1;
}
if(neednum <= havenum)
{
recv(sockfd,msg,sizeof(MSG),0);
printf("您应付%d元\n",msg->price * neednum);
printf("请付钱(本店不支持找零!):");
scanf("%d",&price);
if(price < msg->price * neednum)
{
printf("请再付%d元!\n",msg->price*neednum - price);
printf("请继续付钱:");
scanf("%d",&price1);
printf("欢迎下次光临!\n");
return 1;
}
printf("欢迎下次光临!\n");
}
else
{
printf("库存不足!\n");
return -1;
}
return 0;
}
int do_tuidan(int sockfd,MSG *msg)
{
msg->type = T;
char buf[64];
printf("请输入你要退的货物名称:");
scanf("%s",msg->name);
printf("请输入你要退货的数量:");
scanf("%d",&msg->num);
send(sockfd,msg,sizeof(MSG),0);
recv(sockfd,buf,sizeof(buf),0);
printf("%s\n",buf);
}
int do_retrieve_passwor(int sockfd,MSG *msg)
{
msg->type=F;
printf("请输入需要找回密码的账号:");
scanf("%s",msg->name);
getchar();
printf("请输入注册手机号码:");
scanf("%s",msg->number);
getchar();
if(send(sockfd,msg,sizeof(MSG),0)<0)
{
printf("fail to send\n");
return -1;
}
if(recv(sockfd,msg,sizeof(MSG),0)<0)
{
printf("fail to recv\n");
return -1;
}
printf("验证消息:%s \n",msg->passwd);
return 0;
}
int do_history(int sockfd,MSG *msg)
{
msg->type=H;
int i;
char buf[256];
if(send(sockfd,msg,sizeof(MSG),0)<0)
{
printf("fail to send\n");
return -1;
}
while(1)
{
bzero(buf,256);
recv(sockfd,buf,256,0);
if(buf[0] == '\0')
break;
printf("%s\n",buf);
}
}
main.c
#include "client.h"
int main(int argc, char *argv[])
{
int sockfd,n;
struct sockaddr_in serveraddr;
MSG msg;
GOODS good;
if(argc != 3)
{
printf("Usagr:%s serverip port.\n",argv[0]);
return -1;
}
if((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
{
perror("socket");
exit(1);
}
bzero(&serveraddr,sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
serveraddr.sin_port = htons(atoi(argv[2]));
if(connect(sockfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr)) < 0)
{
perror("connect");
exit(1);
}
rt:
while(1)
{
int ret;
printf("\033[44;1m**************壮壮哥线上烟酒超市************\033[0m\n");
printf("** 1.注册 2.登录 3.退出 4.找回密码 5.注销 **\n");
printf("\033[44;1m********************************************\033[0m\n");
scanf("%d",&n);
getchar();
switch(n)
{
case 1:
do_register(sockfd,&msg);
break;
case 2:
if((ret = do_login(sockfd,&msg)) == 1)
{
goto next;
break;
}
break;
case 3:
close(sockfd);
exit(0);
break;
case 5:
do_distroy(sockfd,&msg);
break;
case 4:
do_retrieve_passwor(sockfd,&msg);
break;
default:
printf("Invalid data cmd.\n");
}
}
next:
while(1)
{
do_select(sockfd,&msg,&good);
scanf("%d",&n);
getchar();
switch(n)
{
case 1:shopping(sockfd,&msg);
break;
case 3:
do_history(sockfd,&msg);
break;
case 4:
close(sockfd);
exit(0);
break;
case 5:
goto rt;
break;
case 2:
do_tuidan(sockfd,&msg);
break;
default:
printf("Invalid data cmd.\n");
}
}
return 0;
}
server.h
#ifndef _SERVER_H_
#define _SERVER_H_
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <sqlite3.h>
#include <signal.h>
#include <time.h>
#define N 32
#define R 1 //user - register
#define L 2 //user - login
#define Q 3 //user - query
#define H 4 //user - history
#define D 5 //user - distroy
#define F 6 //user - retrieve_password
#define S 7 //goods - select
#define T 8
#define DATABASE "store.db"
//定义通信双方的信息结构体
typedef struct {
int type;
char name[16];
char passwd[64];
char number[12];
int price ;
int num;
}MSG;
typedef struct {
char name[32];
char num[16];
char price[16];
}GOODS;
int do_client(int acceptfd,sqlite3 *db);
void do_register(int acceptfd,MSG *msg,sqlite3 *db);
int do_destroy(int acceptfd,MSG *msg,sqlite3 *db);
int do_login(int acceptfd,MSG *msg,sqlite3 *db);
int do_query(int acceptfd,MSG *msg,sqlite3 *db);
int do_history(int acceptfd,MSG *msg,sqlite3 *db);
int get_date(char *date);
int do_retrieve_passwor(int acceptfd,MSG *msg,sqlite3 *db);
void do_select(int acceptfd,MSG *msg,GOODS *good,sqlite3 *db);
int do_tuidan(int acceptfd,MSG *msg,sqlite3 *db);
#endif
server.c
#include "server.h"
void do_select(int acceptfd,MSG *msg,GOODS *good,sqlite3 *db)
{
char buf[45];
char *errmsg;
char **resultp;
char sql[128];
int nrow,ncloum,j;
char number[12] = {
0};
sprintf(sql,"select * from goods; ");
printf("%s\n",sql);
if(sqlite3_get_table(db,sql,&resultp,&nrow,&ncloum,&errmsg) != SQLITE_OK)
{
printf("%s\n",errmsg);
return ;
}
else
{
printf("%d %d %s\n",nrow,ncloum,resultp[0]);
printf("get table ok!\n");
for(int j=1;j<=nrow;j++)
{
bzero(buf,45);
sprintf(buf,"****%8s *** %2s *** ¥%5s ***",resultp[3*j+0],resultp[3*j+1],resultp[j*3+2]);
printf("%s \n",buf);
send(acceptfd,buf,45,0);
usleep(10);
}
}
}
int do_client(int acceptfd,sqlite3 *db)
{
MSG msg;
GOODS good;
char data[64];
char goods[128];
while(recv(acceptfd,&msg,sizeof(msg),0) > 0)
{
printf("type: %d\n",msg.type);
switch(msg.type)
{
case R:
do_register(acceptfd,&msg,db);
break;
case L:
do_login(acceptfd,&msg,db);
break;
case Q:
do_query(acceptfd,&msg,db);
break;
case H:
do_history(acceptfd,&msg,db);
break;
case D:
do_destroy(acceptfd,&msg,db);
break;
case F:
do_retrieve_passwor(acceptfd,&msg,db);
break;
case S:
do_select(acceptfd,&msg,&good,db);
break;
case T:
do_tuidan(acceptfd,&msg,db);
break;
default:
printf("Invalid msg.\n");
}
}
printf("client exit.\n");
close(acceptfd);
return 0;
}
void do_register(int acceptfd,MSG *msg,sqlite3 *db)
{
char *errmsg;
char sql[128];
sprintf(sql,"insert into user values('%s','%s','%s');",msg->name,msg->passwd,msg->number);
printf("%s\n",sql);
if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK)
{
printf("%s\n",errmsg);
strcpy(msg->passwd,"帐号已存在.");
}
else
{
printf("注册成功!\n");
strcpy(msg->passwd,"ok!");
}
if(send(acceptfd,msg,sizeof(MSG),0) < 0)
{
printf("fail to send.\n");
return;
}
}
int do_destroy(int acceptfd,MSG *msg,sqlite3 *db)
{
char *errmsg;
char sql[128];
int nrow,ncloumn;
char **resultp;
sprintf(sql,"select * from user where name = '%s' and passwd = '%s';",msg->name,msg->passwd);
printf("%s\n",sql);
if(sqlite3_get_table(db,sql,&resultp,&nrow,&ncloumn,&errmsg) != SQLITE_OK)
{
printf("%s\n",errmsg);
return -1;
}
else
{
printf("get_table ok.\n");
}
if(nrow == 0 )
{
strcpy(msg->passwd,"用户或密码错误!");
send(acceptfd,msg,sizeof(MSG),0);
printf("detele fail 1\n");
}
if(nrow == 1)
{
sprintf(sql,"delete from user where name='%s'and passwd = '%s';",msg->name,msg->passwd);
printf("%s\n",sql);
if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK)
{
printf("%s\n",errmsg);
printf("detele fail2\n");
return -1;
}
else
{
printf("client detele ok!\n");
strcpy(msg->passwd,"注销成功!");
send(acceptfd,msg,sizeof(MSG),0);
return -1;
}
}
}
int do_tuidan(int acceptfd,MSG *msg,sqlite3 *db)
{
char *errmsg,**resultp;
int nrow,ncloumn;
char date[128];
char sql[128],sql1[128],sql2[128];
int num;
printf("%s %d\n",msg->name,msg->num);
sprintf(sql,"select num from goods where name = '%s';",msg->name);
printf("%s\n",sql);
if(sqlite3_get_table(db,sql,&resultp,&nrow,&ncloumn,&errmsg) != SQLITE_OK)
{
printf("%s\n",errmsg);
return -1;
}
printf("现有库存为:%d\n",atoi(resultp[1]));
num = atoi(resultp[1]);
printf("num %d\n",msg->num + num);
printf("name %s\n",msg->name);
sprintf(sql1,"update goods set num = %d where name = '%s';",msg->num + num,msg->name);
printf("sql = %s\n",sql);
if(sqlite3_exec(db,sql1,NULL,NULL,&errmsg) != SQLITE_OK)
{
printf("%s\n",errmsg);
return -1;
}
printf("update success!\n");
send(acceptfd,"退货成功!",20,0);
get_date(date);
sprintf(sql2,"insert into record values('%s','+%d','%s');",msg->name,msg->num,date);
if(sqlite3_exec(db,sql2,NULL,NULL,&errmsg) != SQLITE_OK)
{
printf("%s\n",errmsg);
return -1;
}
printf("insert record down!\n");
return 0;
}
int do_login(int acceptfd,MSG *msg,sqlite3 *db)
{
char *errmsg;
char sql[128];
char **resultp;
int nrow,ncloumn;
sprintf(sql,"select * from user where name = '%s' and passwd = '%s';",msg->name,msg->passwd);
printf("%s\n",sql);
if(sqlite3_get_table(db,sql,&resultp,&nrow,&ncloumn,&errmsg) != SQLITE_OK)
{
printf("%s\n",errmsg);
return -1;
}
else
{
printf("get_table ok.\n");
}
//查询成功,数据库中拥有此用户
if(nrow == 1)
{
strcpy(msg->passwd,"OK");
send(acceptfd,msg,sizeof(MSG),0);
return 1;
}
if(nrow == 0)//密码或用户名错误
{
strcpy(msg->passwd,"usr or password wrong!");
send(acceptfd,msg,sizeof(MSG),0);
}
return 0;
}
int do_retrieve_passwor(int acceptfd,MSG *msg,sqlite3 *db )
{
char *errmsg;
char **resultp;
char sql[128];
int nrow,ncloum;
char number[12] = {
0};
sprintf(sql,"select * from user where name = '%s' and number= '%s';",msg->name,msg->number);
printf("%s\n",sql);
if(sqlite3_get_table(db,sql,&resultp,&nrow,&ncloum,&errmsg) != SQLITE_OK)
{
printf("%s\n",errmsg);
return -1;
}
else
{
printf("get table ok!\n");
}//验证成功
if(nrow == 1)
{
sprintf(sql,"select * from user where name='%s';",msg->name);
if(sqlite3_get_table(db,sql,&resultp,&nrow,&ncloum,&errmsg) != SQLITE_OK)
{
printf("%s\n",errmsg);
return -1;
}
else
{
printf("%s",resultp[4]);
strcpy(msg->passwd,resultp[4]);
send(acceptfd,msg,sizeof(MSG),0);
return 1;
}
}
if(nrow == 0)//验证失败
{
strcpy(msg->passwd,"用户验证失败!");
send(acceptfd,msg,sizeof(MSG),0);
}
return 0;
}
int get_date(char *date)
{
time_t t;
time(&t);
struct tm *tp;
//进行时间的格式转换
tp = localtime(&t);
sprintf(date,"%d-%d-%d %d:%d:%d",tp->tm_year + 1900,tp->tm_mon + 1,tp->tm_mday,tp->tm_hour,tp->tm_min,tp->tm_sec);
return 0;
}
int do_query(int acceptfd,MSG *msg,sqlite3 *db)
{
char *errmsg;
char date[128];
char sql[128],sql2[128],sql3[128];
char name[64];
char **resultp,**resultp1;
int nrow,ncloumn;
int currentnum,neednum;
printf("%s\n",msg->passwd);
sprintf(sql,"select num from goods where name = '%s';",msg->passwd);
strcpy(name,msg->passwd);
printf("name = %s\n",name);
printf("%s\n",sql);
if(sqlite3_get_table(db,sql,&resultp,&nrow,&ncloumn,&errmsg) != SQLITE_OK)
{
printf("%s\n",errmsg);
return -1;
}
if(nrow == 1)
{
printf("现有库存为:%d\n",atoi(resultp[1]));
msg->num = atoi(resultp[1]);
send(acceptfd,msg,sizeof(MSG),0);
}
else
{
strcpy(msg->passwd,"没货");
send(acceptfd,msg,sizeof(MSG),0);
}
currentnum = msg->num; //num为当前按库存;
recv(acceptfd,msg,sizeof(MSG),0);
neednum = msg->num;
printf("neednum = %d\n",msg->num);
sprintf(sql2,"select price from goods where name = '%s';",name);
if(sqlite3_get_table(db,sql2,&resultp1,&nrow,&ncloumn,&errmsg) != SQLITE_OK)
{
printf("%s\n",errmsg);
return -1;
}
printf("price = %s\n",resultp1[1]);
msg->price= atoi(resultp1[1]) ;
send(acceptfd,msg,sizeof(MSG),0);
if(currentnum >= neednum)
{
char buf[128];
sprintf(buf,"update goods set num = %d where name = '%s';",currentnum - neednum,msg->passwd);
printf("%s\n",buf);
if(sqlite3_exec(db,buf,NULL,NULL,&errmsg) != SQLITE_OK)
{
printf("%s\n",errmsg);
return -1;
}
printf("update success!\n");
get_date(date);
sprintf(sql3,"insert into record values('%s','-%d','%s');",name,neednum ,date);
if(sqlite3_exec(db,sql3,NULL,NULL,&errmsg) != SQLITE_OK)
{
printf("%s\n",errmsg);
}
}
return 0;
}
int do_history(int acceptfd,MSG *msg,sqlite3 *db)
{
char buf[256];
char *errmsg;
char **resultp;
char sql[128];
int nrow,ncloum,j;
sprintf(sql,"select * from record;");
printf("%s\n",sql);
if(sqlite3_get_table(db,sql,&resultp,&nrow,&ncloum,&errmsg) != SQLITE_OK)
{
printf("%s\n",errmsg);
return -1;
}
else
{
printf("%5d %2d %10s\n",nrow,ncloum,resultp[0]);
printf("get table ok!\n");
for(int j=0;j<=nrow;j++)
{
bzero(buf,256);
sprintf(buf,"%7s %2s %10s",resultp[3*j+0],resultp[3*j+1],resultp[j*3+2]);
printf("%s \n",buf);
send(acceptfd,buf,256,0);
// usleep(10);
}
buf[0] = '\0';
send(acceptfd,buf,256,0);
}
return 0;
}
main.c
#include "server.h"
int main(int argc, char *argv[])
{
char *data;
int sockfd,n,acceptfd;
struct sockaddr_in serveraddr;
MSG msg;
sqlite3 *db;
char *errmsg;
pid_t pid;
if(argc != 3)
{
printf("Usagr:%s serverip port.\n",argv[0]);
return -1;
}
//打开数据库
if(sqlite3_open(DATABASE,&db) != SQLITE_OK)
{
printf("%s\n",sqlite3_errmsg(db));
return -1;
}
else
{
printf("open DATABASE success.\n");
}
if((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
{
perror("socket");
exit(1);
}
bzero(&serveraddr,sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
serveraddr.sin_port = htons(atoi(argv[2]));
if(bind(sockfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr)) < 0)
{
perror("faile to bind.\n");
return -1;
}
//将套接字设为监听模式
if(listen(sockfd,5) < 0)
{
perror("fail to listen.\n");
return -1;
}
//处理僵尸进程
signal(SIGCHLD,SIG_IGN);
while(1)
{
if((acceptfd = accept(sockfd,NULL,NULL)) < 0)
{
perror("fail to accept.\n");
return -1;
}
else
{
printf("OK!\n");
}
if((pid = fork()) < 0)
{
perror("fail ti fork.\n");
return -1;
}
else if(pid == 0) //子进程
{
//处理客户端具体的信息
close(sockfd);
do_client(acceptfd,db);
}
else//父进程,用来接收客户端的请求
{
close(acceptfd);
}
}
return 0;
}
数据库信息如下: