服务器
fun.c
#ifndef __FUNS_H__
#define __FUNS_H__
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <signal.h>
#include <dirent.h>
#include <errno.h>
#include <strings.h>
#include <sqlite3.h>
#include <sys/epoll.h>
#include <time.h>
#define PORT 8881
#define IP "192.168.250.100"
typedef struct staff_info{
int id; // 员工编号
int usertype; // ADMIN 0 USER 1
char name[20]; // 姓名
char passwd[20]; // 密码
int age; // 年龄
char phone[20]; // 电话
char addr[64]; // 地址
char work[20]; // 职位
char date[20]; // 入职年月
int level; // 等级
double salary ; // 工资
}staff_info_t;
typedef struct {
int msgtype; //请求的消息类型
int usertype; //ADMIN 1 USER 2
char username[20]; //姓名
char passwd[20]; //登陆密码
char recvmsg[64]; //通信的消息
int flags; //标志位
staff_info_t info; //员工信息
}MSG;
//回收僵尸进程
int sighandler(void);
//设置网络属性
int set_network(int sfd);
//创建用户信息表
int set_user_form(sqlite3* db);
//创建历史记录表
int set_history_form(sqlite3* db);
//管理用户模式
int do_administrator(sqlite3* db,int newfd);
//普通用户模式
int do_ordinary(sqlite3* db,int newfd);
//添加
int add_user(sqlite3* db,int newfd);
//按人名查询
int query_info(sqlite3* db,int newfd);
//查询所有
int query_all(sqlite3* db,int newfd);
//修改
int revise_info(sqlite3* db,int newfd);
//修改个人信息
int revise_myself(sqlite3* db,int newfd);
//删除
int Record_user(sqlite3* db,int newfd);
//查询历史记录
int history_Record(sqlite3* db,int newfd);
#endif
main.c
#include "fun.h"
MSG msg;
MSG his;
int main(int argc,const char * argv[])
{
//回收僵尸进程
sighandler();
//创建流试套接字
int sfd = socket(AF_INET,SOCK_STREAM,0);
if(sfd<0)
{
perror("socket");
return -1;
}
//设置网络属性
set_network(sfd);
//创建并打开数据库
sqlite3 *db = NULL;
if(sqlite3_open("./my.db",&db)!=SQLITE_OK)
{
printf("sqlite3_open:%d\n",sqlite3_errcode(db));
return -1;
}
//创建用户信息表
set_user_form(db);
//创建历史记录表
set_history_form(db);
int newfd = 0;
struct sockaddr_in sin;
socklen_t addrlen = sizeof(sin);
while(1)
{
//accept函数由父进程来执行
newfd = accept(sfd,(struct sockaddr*)&sin,&addrlen);
if(newfd<0)
{
perror("accept");
return -1;
}
printf("[%s:%d]客户端连接成功\n",inet_ntoa(sin.sin_addr),\
ntohs(sin.sin_port));
pid_t pid = fork();
if(pid>0)
{
close(newfd);
}
//子进程进行与客户端的交互
else if(pid==0)
{
close(sfd);
int res = 0;
while(1)
{
bzero(&msg,sizeof(msg));
res = recv(newfd,&msg,sizeof(msg),0);
if(res<0)
{
perror("recv");
return -1;
}
else if(res==0)
{
printf("[%s:%d]客户端断开\n",inet_ntoa(sin.sin_addr),\
ntohs(sin.sin_port));
close(newfd);
return -1;
}
//判断客户端要使用的功能
switch(msg.msgtype)
{
case 0:
//管理用户模式
bzero(&his,sizeof(his));
his = msg;
do_administrator(db,newfd);
break;
case 1:
//普通用户模式
do_ordinary(db,newfd);
break;
case 2:
//按人名查询
query_info(db,newfd);
break;
case 3:
//修改
revise_info(db,newfd);
break;
case 4:
//添加
add_user(db,newfd);
break;
case 5:
//删除
Record_user(db,newfd);
break;
case 6:
//查询历史记录
history_Record(db,newfd);
break;
case 7:
//退出登录
break;
case 8:
//查询所有
query_all(db,newfd);
break;
case 9:
//修改个人信息
revise_myself(db,newfd);
break;
}
}
}
}
close(sfd);
return 0;
}
fun.c
#include "fun.h"
extern MSG msg;
extern MSG his;
//回收僵尸进程
typedef void(*sighandler_t)(int);
void handler(int sig)
{
while(waitpid(-1,NULL,WNOHANG)>0);
}
int sighandler()
{
sighandler_t s = signal(17,handler);
if(s==SIG_ERR)
{
perror("signal");
return -1;
}
return 0;
}
//设置网络属性
int set_network(int sfd)
{
//允许端口快速被重用
int reuse = 1;
if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))<0)
{
perror("setsockopt");
return -1;
}
//获取服务器地址信息的结构体
struct sockaddr_in sin;
socklen_t addrlen = sizeof(sin);
sin.sin_family = AF_INET; //必须填AF_INET
sin.sin_port = htons(PORT); //端口号的网络字节序;(1024~49151)
sin.sin_addr.s_addr = inet_addr(IP); //本机IP地址
//绑定服务器端口号与ip
if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))<0)
{
perror("bind");
return -1;
}
//将套接字设置为被动监听状态
if(listen(sfd,128)<0)
{
perror("listen");
return -1;
}
printf("服务器开启监听\n");
return 0;
}
//创建用户信息表
int set_user_form(sqlite3* db)
{
staff_info_t info;
char* errmsg = NULL;
char sql[256] = "create table if not exists user(id int PRIMARY KEY,type int,name char, password char,age int,phone char,addr char,work char,data char,level int,salary double);";
if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
{
fprintf(stderr,"sqlite3_exec:%s\n",errmsg);
return -1;
}
//存入一个管理员用户
info.id = 1001;
info.usertype = 0;
strcpy(info.name,"Bill");
//info.name[20] = "Bill";
strcpy(info.passwd,"716815");
info.age = 23;
strcpy(info.phone,"187149398xx");
strcpy(info.addr,"myhome");
strcpy(info.work,"writer");
strcpy(info.date,"2023.2.27");
info.level = 10;
info.salary = 30000;
bzero(sql,sizeof(sql));
sprintf(sql,"insert into user values (1001,0,\"%s\",\"%s\",23,\"%s\",\"%s\",\"%s\",\"%s\",10,30000);",info.name,info.passwd,info.phone,info.addr,info.work,info.date);
if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
{
return -1;
}
return 0;
}
//创建历史记录表
int set_history_form(sqlite3* db)
{
char* errmsg = NULL;
char sql[256] = "create table if not exists history_Record(data char,name char,events char);";
if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
{
fprintf(stderr,"sqlite3_exec:%s\n",errmsg);
return -1;
}
bzero(sql,sizeof(sql));
strcpy(sql,"delete from history_Record;");
if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
{
fprintf(stderr,"sqlite3_exec:%s\n",errmsg);
return -1;
}
return 0;
}
//管理用户模式
int do_administrator(sqlite3* db,int newfd)
{
//判断登录是否正确
char* errmsg = NULL;
char** pres = NULL;
int row,column;
char sql[64] = "SELECT * FROM user;";
if(sqlite3_get_table(db,sql,&pres,&row,&column,&errmsg)!=SQLITE_OK)
{
fprintf(stderr,"sqlite3_get_table:%s\n",errmsg);
return -1;
}
//循环获取user表中的值
int line;
int i = column+2;
for(line=0;line<row;line++)
{
//判断用户名是否正确
if(strcmp(msg.info.name,pres[i])!=0)
{