一、项目要求
1.一个root用户
权限有:屏幕管理,用户管理,日志管理
1)屏幕管理:
当新增一个屏幕,由PC管理端,编辑信息发送到linux服务端,linux服务端接收信息,服务端会修改数据库里的信息;主要有对屏幕的增删改查
屏幕信息主要包括屏幕位置、屏幕尺寸、屏幕厂商信息、屏幕序列号、屏幕安装时间等等
2)用户管理
超级用户登陆后,可以增加用户,但不能删除用户(如果用户离职,指挥记录用户离职标记,后续无法再用此用户登录,直接删除会导致用户操作日志无法溯源),除此以外还包括了用户的改和查
用户信息包括:用户名、用户身份证信息、用户职位、用户手机号、用户邮箱、用户入职时间离职标记等等
3)日志管理
可以查看日志
2.普通用户
权限有:修改密码、查看在线屏幕、选择屏幕发送消息、选择屏幕发送文件
二、项目思路
需要搭建服务器端,客户端以及屏幕端,还要搭建服务器。
一个模块一个模块来写
除此以外,还有客户端请求,服务端处理请求,日志,登录,链表,界面,数据库等等模块需要封装
在线屏幕以及用户信息将用链表储存(包括序列号/用户名和它们的套接字),每当客户端退出时,从在线链表里剔除对用客户端
三、代码
1. .c文件
1)server.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/epoll.h>
#include <string.h>
#include "pack.h"
#include "mysql.h"
#include "log.h"
#include "list.h"
#include "deal_request.h"
//套接字初始化
int sock_init(){
int sockfd;
int ret;
sockfd = socket(AF_INET,SOCK_STREAM,0);//创建套接字
if(sockfd<0){
perror("socket");
return -1;
}
//设置套接字端口复用
int opt = 1;
setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
//设置地址族结构体
struct sockaddr_in seraddr;
int addrlen = sizeof(struct sockaddr_in);
seraddr.sin_family = AF_INET;
seraddr.sin_port = htons(6688);
inet_pton(AF_INET,"127.0.0.1",&seraddr.sin_addr.s_addr);
ret = bind(sockfd,(struct sockaddr*)&seraddr,addrlen);//绑定地址和端口号
if(ret<0){
perror("bind");
return -1;
}
ret = listen(sockfd,10);//通知内核监听套接字
if(ret<0){
perror("listen");
return -1;
}
return sockfd;//返回套接字
}
int main(){
struct user_pk *head = NULL;
head = create_node();//客户端链表,用来存储已经连接上的用户和它的套接字
struct screen_pk *head1 = NULL;
head1 = create_node1();//屏幕端链表,用来存储已经连接上的屏幕和它的套接字
int sockfd,ret,count,cfd,efd,port;
char ip[64];
struct sockaddr_in cliaddr;
int addrlen = sizeof(struct sockaddr_in);
//连接数据库
ret = my_init();
if(ret<0){
return -1;
}
//epoll
efd = epoll_create(100);//创建集合空间
if(efd<0){
perror("epoll_create");
return -1;
}
//生成套接字
sockfd = sock_init();
if(sockfd<0){
return -1;
}
struct epoll_event ev;
struct epoll_event evs[10];
ev.events = EPOLLIN;
ev.data.fd = sockfd;
epoll_ctl(efd,EPOLL_CTL_ADD,sockfd,&ev);//管理集合空间中的文件描述符
while(1){
printf("服务器等待响应...\n");
count = epoll_wait(efd,evs,10,-1);//监听集合中的文件描述符
if(count<0){
perror("epoll_wait");
break;
}
for(int i=0;i<count;i++){
int temp = evs[i].data.fd;
if(temp == sockfd){ //有客户端请求连接
//1.接受客户端
cfd = accept(sockfd,(struct sockaddr*)&cliaddr,&addrlen);
port = ntohs(cliaddr.sin_port);
inet_ntop(AF_INET,&cliaddr.sin_addr.s_addr,ip,64);
printf("客户端[%s:%d]连接成功!\n",ip,port);
if(cfd<0){
perror("accept");
continue;
}
//2.cfd加入efd关联集合中
ev.data.fd = cfd;
epoll_ctl(efd,EPOLL_CTL_ADD,cfd,&ev);
}
else{ //客户有请求
struct pack pk;
ret = read(temp,&pk,sizeof(struct pack));//读包
if(ret<0){
perror("read");
close(temp); //关闭文件描述符
epoll_ctl(efd,EPOLL_CTL_DEL,temp,NULL); //从集合中移除
continue;
}
else if(ret == 0){
printf("客户端断开连接!\n");
close(temp); // 关闭文件描述符
epoll_ctl(efd,EPOLL_CTL_DEL,temp,NULL); //从集合中移除
if(head->next == NULL&&head1->next == NULL){ //每当客户或者屏幕断开连接时,将其从链表中剔除
continue;
}
else{
if(head->next!=NULL){
struct user_pk *p = head->next;
while(p!=NULL){
if(p->fd == temp){
del_user_list(head,temp);
break;
}
p = p->next;
}
}
if(head1->next!=NULL){
struct screen_pk *t =head1->next;
while(t!=NULL){
if(t->fd == temp){
del_screen_list(head1,temp);
break;
}
t = t->next;
}
}
continue;
}
}
if(pk.type == LOG){ //处理root用户登录请求
deal_root_login_request(temp,efd);
}
else if(pk.type == LOG2){ //处理普通用户登录请求
deal_user_login_request(temp,efd,head);
}
else if(pk.type == SCR_LOG){ //处理屏幕登录请求
deal_screen_login_request(temp,efd,head1);
}
else if(pk.type == SCR_ADD){ //处理增加屏幕请求
deal_add_screen_request(temp,efd);
}
else if(pk.type == SCR_DEL){ //处理删除屏幕请求
deal_del_screen_request(temp,efd);
}
else if(pk.type == SCR_MOD){ //处理修改屏幕请求
deal_mod_screen_request(temp,efd);
}
else if(pk.type == SCR_SHOW){ //处理展示屏幕请求
deal_show_screen_request(temp,efd);
}
else if(pk.type == USER_ADD){ //处理增加用户请求
deal_add_user_request(temp,efd);
}
else if(pk.type == USER_DEL){ //处理删除用户请求
deal_del_user_request(temp,efd);
}
else if(pk.type == USER_MOD){ //处理修改用户请求
deal_mod_user_request(temp,efd);
}
else if(pk.type == USER_SHOW){ //处理展示用户信息请求
deal_show_user_request(temp,efd);
}
else if(pk.type == USER_MOD_PSWD){ //处理用户修改密码请求
deal_mod_pswd_request(temp,efd,head);
}
else if(pk.type == SHOW_ON){ //处理展示当前在线屏幕请求
deal_show_online_screen_request(temp,efd,head1);
}
else if(pk.type == MESS){ //处理向屏幕发送消息请求
deal_message_request(temp,efd,head,head1);
}
else if(pk.type == SEND_FILE){ //处理向屏幕发送文件请求
deal_file_request(temp,efd,head,head1);
}
}
}
}
my_close();
close(cfd);
close(sockfd);
free_user_pk(head);
free_screen_pk(head1);
return 0;
}
2)client.c
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <signal.h>
#include "pack.h"
#include "menu.h"
#include "login.h"
#include "list.h"
#include "client_request.h"
//打开root用户日志
void open_root_log(){
int ch;
FILE *fp;
char fname[50] = "./日志/root.log";
fp = fopen(fname,"r");
if(fp == NULL){
printf("打开失败!\n");
return;
}
while((ch = getc(fp))!=EOF){
putchar(ch);
}
fclose(fp);
return;
}
//打开普通用户日志
void open_user_log(){
int ch;
FILE *fp;
char fname[50] = "./日志/user.log";
fp = fopen(fname,"r");
if(fp == NULL){
printf("打开失败!\n");
return;
}
while((ch = getc(fp))!=EOF){
putchar(ch);
}
fclose(fp);
return;
}
void hangle(int sig){
printf("rev sig:%d\n",sig);
}
int main(){
signal(SIGPIPE,hangle);//遇到SIGPIPE信号执行hangle函数
int sockfd,ret;
int flag = 1;
int sel,sel1,sel2,sel3,sel4,sel5;
sockfd = socket(AF_INET,SOCK_STREAM,0);//创建监听套接字
if(sockfd<0){
perror("socket");
return -1;
}
//设置地址族
struct sockaddr_in seraddr;
int addrlen = sizeof(struct sockaddr_in);
seraddr.sin_family = AF_INET;
seraddr.sin_port = htons(6688);
inet_pton(AF_INET,"127.0.0.1",&seraddr.sin_addr.s_addr);
ret = connect(sockfd,(struct sockaddr*)&seraddr,addrlen);//请求连接
if(ret<0){
perror("connect");
return -1;
}
while(flag){
int flag1 = 1;
int flag5 = 1;
menu1();
scanf("%d",&sel);
while(getchar()!='\n');
switch(sel){
case 1: //root用户登录
ret = root_login_request(sockfd);
if(ret == 1){ //登录成功进入下级操作页面
while(flag1){
int flag2 = 1;
int flag3 = 1;
int flag4 = 1;
menu2();
scanf("%d",&sel1);
while(getchar()!='\n');
switch(sel1){
case 1: //管理屏幕
while(flag2){
menu3();
scanf("%d",&sel2);
while(getchar()!='\n');
switch(sel2){
case 1: //增加新屏幕
add_screen_request(sockfd);
break;
case 2: //删除屏幕
del_screen_request(sockfd);
break;
case 3: //修改屏幕
mod_screen_request(sockfd);
break;
case 4: //查看所有屏幕信息
show_screen_request(sockfd);
break;
case 0:
flag2 = 0;
break;
default:
printf("无效输入,请重新输入\n");
break;
}
}
break;
case 2: //管理用户
while(flag3){
menu4();
scanf("%d",&sel3);
while(getchar()!='\n');
switch(sel3){
case 1: //增加新用户
add_user_request(sockfd);
break;
case 2: //删除用户
del_user_request(sockfd);
break;
case 3: //修改用户
mod_user_request(sockfd);
break;
case 4: //查看所有用户信息
show_user_request(sockfd);
break;
case 0:
flag3 = 0;
break;
default:
printf("无效输入,请重新输入\n");
break;
}
}
break;
case 3: //查看日志
while(flag4){
menu5();
scanf("%d",&sel4);
while(getchar()!='\n');
switch(sel4){
case 1: //查看root用户日志
open_root_log();
break;
case 2: //查看普通用户日志
open_user_log();
break;
case 0:
flag4 = 0;
break;
default:
printf("无效输入,请重新输入\n");
break;
}
}
break;
case 0:
flag1 = 0;
break;
default:
printf("无效输入,请重新输入!\n");
break;
}
}
}
break;
case 2: //普通用户登录
ret = user_login_request(sockfd);
if(ret == 1){
while(flag5){
menu6();
scanf("%d",&sel5);
while(getchar()!='\n');
switch(sel5){
case 1: //修改密码
mod_pswd_request(sockfd);
break;
case 2: //显示在线屏幕
show_online_screen(sockfd);
break;
case 3: //选择屏幕发送消息
choose_to_message(sockfd);
break;
case 4: //选择屏幕发送文件
choose_to_file(sockfd);
break;
case 0:
flag5 = 0;
break;
default:
printf("无效输入,请重新输入!\n");
break;
}
}
}
break;
case 0:
flag = 0;
break;
default:
printf("无效输入,请重新输入!\n");
break;
}
}
close(sockfd);
return 0;
}
3)screen.c
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <signal.h>
#include "pack.h"
void hangle(int sig){
printf("rev sig:%d\n",sig);
}
int main(){
signal(SIGPIPE,hangle);
int sockfd,ret;
char number[18];
sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd<0){
perror("socket");
return -1;
}
struct sockaddr_in seraddr;
int addrlen = sizeof(struct sockaddr_in);
seraddr.sin_family = AF_INET;
seraddr.sin_port = htons(6688);
inet_pton(AF_INET,"127.0.0.1",&seraddr.sin_addr.s_addr);
ret = connect(sockfd,(struct sockaddr*)&seraddr,addrlen);
if(ret<0){
perror("connect");
return -1;
}
struct pack pk;
pk.ver = 1;
pk.type = SCR_LOG;
pk.len = 0;
ret = write(sockfd,&pk,sizeof(struct pack));
if(ret<0){
perror("write");
close(sockfd);
exit(-1);
}
printf("序列号:");
scanf("%s",number);
while(getchar()!='\n');
ret = write(sockfd,number,strlen(number));
if(ret<0){
perror("write");
close(sockfd);
exit(-1);
}
ret = read(sockfd,&pk,sizeof(struct pack));
if(ret<0){
perror("read");
close(sockfd);
exit(-1);
}
else if(ret == 0){
printf("服务器断开连接!\n");
close(sockfd);
exit(-1);
}
if(pk.type == LOG_OK){
printf("登录成功!\n");
}
else if(pk.type == LOG_FAIL_NONAME){
printf("登录失败,序列号不存在!\n");
exit(-1);
}
else if(pk.type == LOG_FLAG0){
printf("该屏幕已拆除!\n");
exit(-1);
}
else if(pk.type == RELOG){
printf("该屏幕已在线!\n");
exit(-1);
}
char buff[1024];
while(1){
ret = read(sockfd,buff,1024);
if(ret<0){
perror("read");
close(sockfd);
exit(-1);
}
else if(ret == 0){
printf("服务器断开连接!\n");
close(sockfd);
exit(-1);
}
buff[ret] = '\0';
printf("%s\n",buff);
}
return 0;
}
4)deal_request.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/epoll.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include "pack.h"
#include "mysql.h"
#include "log.h"
#include "list.h"
static void read_error(int ret,int cfd,int efd){
if(ret<0){
perror("read");
close(cfd);
epoll_ctl(efd,EPOLL_CTL_DEL,cfd,NULL);
return;
}
else if(ret == 0){
close(cfd);
epoll_ctl(efd,EPOLL_CTL_DEL,cfd,NULL);
return;
}
}
static void write_error(int ret,int cfd,int efd){
if(ret<0){
perror("write");
close(cfd);
epoll_ctl(efd,EPOLL_CTL_DEL,cfd,NULL);
return;
}
}
//处理root登录请求
int deal_root_login_request(int cfd,int efd){
int ret;
struct root r1;
ret = read(cfd,&r1,sizeof(struct root));
read_error(ret,cfd,efd);
struct pack pk;
pk.ver = 1;
pk.type = LOG_OK;
pk.len = 0;
char sql[1024];
int rows = 0;
MYSQL_RES *result = NULL;
sprintf(sql,"select *from root where 用户名='%s'",r1.name);
my_go(sql,&result);
rows = mysql_num_rows(result);
if(rows == 0){
pk.type = LOG_FAIL_NONAME;
}
else{
MYSQL_ROW row = NULL;
row = mysql_fetch_row(result);
if(strcmp(r1.name,row[0]) == 0){
if(strcmp(r1.pswd,row[1]) == 0){
pk.type = LOG_OK;
sprintf(sql,"root用户[%s]登录系统",r1.name);
log_root(sql);
}
else{
pk.type = LOG_FAIL_WRONGPSWD;
}
}
}
//将结果返回给客户端
ret = write(cfd,&pk,sizeof(struct pack));
write_error(ret,cfd,efd);
return 0;
}
//处理用户登录请求
int deal_user_login_request(int cfd,int efd,struct user_pk *head){
int ret;
struct root r2;
ret = read(cfd,&r2,sizeof(struct root));
read_error(ret,cfd,efd);
struct pack pk;
pk.ver = 1;
pk.type = LOG_OK;
pk.len = 0;
char sql[1024];
int rows = 0;
MYSQL_RES *result = NULL;
sprintf(sql,"select *from user_info where 用户名='%s'",r2.name);
my_go(sql,&result);
rows = mysql_num_rows(result);
if(rows == 0){
pk.type = LOG_FAIL_NONAME;
}
else{
MYSQL_ROW row = NULL;
for(int i=1;i<=rows;i++){
row = mysql_fetch_row(result);
int f = atoi(row[0]);
if(strcmp(r2.name,row[1]) == 0){
if(strcmp(r2.pswd,row[2]) == 0&&f == 1){
pk.type = LOG_OK;
struct user_pk *pnew = NULL;
pnew = create_node();
pnew->fd = cfd;
strcpy(pnew->name,r2.name);
pnew->next = head->next;
head->next = pnew;
sprintf(sql,"普通用户[%s]登录系统",r2.name);
log_user(sql);
break;
}
else if(strcmp(r2.pswd,row[2]) == 0&&f == 0){
pk.type = LOG_FLAG0;
break;
}
else{
pk.type = LOG_FAIL_WRONGPSWD;
break;
}
}
}
}
ret = write(cfd,&pk,sizeof(struct pack));
write_error(ret,cfd,efd);
return 0;
}
//处理增加新屏幕请求
int deal_add_screen_request(int cfd,int efd){
int ret;
struct screen s1;
ret = read(cfd,&s1,sizeof(struct screen));
read_error(ret,cfd,efd);
//将屏幕信息写入数据库
char sql[1024];
int rows = 0;
MYSQL_RES *result = NULL;
sprintf(sql,"insert into screen_info values (%d,'%s','%s','%s','%s','%s')",\
s1.flag,s1.num,s1.pos,s1.size,s1.firm,s1.settime);
ret = my_go(sql,&result);
if(ret == 0){
sprintf(sql,"root用户admin增加了新屏幕,序列号为[%s]",s1.num);
log_root(sql);
}
struct pack pk;
pk.ver = 1;
pk.type = SCR_ADD_OK;
pk.len = 0;
if(ret<0){
pk.type = SCR_ADD_FAIL;
}
ret = write(cfd,&pk,sizeof(struct pack));
write_error(ret,cfd,efd);
return 0;
}
//没有将数据从数据库彻底删除,而是将flag改为0
int deal_del_screen_request(int cfd,int efd){
int ret;
char number[18];
ret = read(cfd,number,18);
number[ret] = '\0';
read_error(ret,cfd,efd);
struct pack pk;
pk.ver = 1;
pk.type = SCR_DEL_OK;
pk.len = 0;
char sql[1024];
int rows = 0;
MYSQL_RES *result = NULL;
sprintf(sql,"select *from screen_info where 序列号='%s'",number);
my_go(sql,&result);
rows = mysql_num_rows(result);
if(rows == 0){
pk.type = SCR_DEL_FAIL;
ret = write(cfd,&pk,sizeof(struct pack));
write_error(ret,cfd,efd);
return 0;
}
else{
MYSQL_ROW row = NULL;
for(int i=1;i<=rows;i++){
row = mysql_fetch_row(result);
if(strcmp(number,row[1]) == 0){
sprintf(sql,"update screen_info set flag=0 where 序列号='%s'",number);
ret = my_go(sql,NULL);
if(ret<0){
pk.type = SCR_DEL_FAIL;
}
else{
pk.type = SCR_DEL_OK;
sprintf(sql,"root用户admin删除了屏幕,序列号为[%s]",number);
log_root(sql);
}
break;
}
}
}
//向客户端反馈
ret = write(cfd,&pk,sizeof(struct pack));
write_error(ret,cfd,efd);
return 0;
}
//处理修改屏幕请求
int deal_mod_screen_request(int cfd,int efd){
int ret;
char number[18];
struct screen s2;
ret = read(cfd,number,18);
number[ret] = '\0';
read_error(ret,cfd,efd);
struct pack pk;
pk.ver = 1;
pk.type = SCR_MOD_OK;
pk.len = 0;
char sql[1024];
int rows = 0;
MYSQL_RES *result = NULL;
sprintf(sql,"select *from screen_info where 序列号='%s'",number);
my_go(sql,&result);
rows = mysql_num_rows(result);
if(rows == 0){
pk.type = SCR_MOD_FAIL;
ret == write(cfd,&pk,sizeof(struct pack));
write_error(ret,cfd,efd);
return 0;
}
else{
ret = read(cfd,&s2,sizeof(struct screen));
read_error(ret,cfd,efd);
sprintf(sql,"update screen_info set flag=%d where 序列号='%s'",s2.flag,number);
my_go(sql,NULL);
sprintf(sql,"update screen_info set 位置='%s' where 序列号='%s'",s2.pos,number);
my_go(sql,NULL);
sprintf(sql,"update screen_info set 尺寸='%s' where 序列号='%s'",s2.size,number);
my_go(sql,NULL);
sprintf(sql,"update screen_info set 厂商信息='%s' where 序列号='%s'",s2.firm,number);
my_go(sql,NULL);
sprintf(sql,"update screen_info set 安装时间='%s' where 序列号='%s'",s2.settime,number);
my_go(sql,NULL);
sprintf(sql,"update screen_info set 序列号='%s' where 序列号='%s'",s2.num,number);
my_go(sql,NULL);
sprintf(sql,"root用户admin修改了序列号为[%s]的屏幕,flag=[%d],位置=[%s],尺寸=[%s],厂商信息=[%s]\
安装时间=[%s],序列号=[%s]",number,s2.flag,s2.pos,s2.size,s2.firm,s2.settime,s2.num);
log_root(sql);
}
ret = write(cfd,&pk,sizeof(struct pack));
write_error(ret,cfd,efd);
return 0;
}
//处理显示所有屏幕信息请求
int deal_show_screen_request(int cfd,int efd){
int ret;
struct screen s3;
char sql[1024];
int rows = 0;
MYSQL_RES *result = NULL;
sprintf(sql,"select *from screen_info");
my_go(sql,&result);
rows = mysql_num_rows(result);
ret = write(cfd,&rows,sizeof(int));
write_error(ret,cfd,efd);
MYSQL_ROW row = NULL;
for(int i=1;i<=rows;i++){
row = mysql_fetch_row(result);
s3.flag = atoi(row[0]);
strcpy(s3.num,row[1]);
strcpy(s3.pos,row[2]);
strcpy(s3.size,row[3]);
strcpy(s3.firm,row[4]);
strcpy(s3.settime,row[5]);
ret = write(cfd,&s3,sizeof(struct screen));
write_error(ret,cfd,efd);
}
return 0;
}
//处理增加新用户请求
int deal_add_user_request(int cfd,int efd){
int ret;
struct user u1;
ret = read(cfd,&u1,sizeof(struct user));
read_error(ret,cfd,efd);
//将用户信息写入数据库
char sql[1024];
int rows = 0;
MYSQL_RES *result = NULL;
sprintf(sql,"insert into user_info values (%d,'%s','%s',%d,'%s',%d,'%s','%s')",\
u1.flag,u1.name,u1.pswd,u1.iden,u1.pos,u1.phone,u1.mail,u1.hiredate);
ret = my_go(sql,&result);
if(ret == 0){
sprintf(sql,"root用户admin增加了新用户,用户名为[%s]",u1.name);
log_root(sql);
}
struct pack pk;
pk.ver = 1;
pk.type = USER_ADD_OK;
pk.len = 0;
if(ret<0){
pk.type = USER_ADD_FAIL;
}
ret = write(cfd,&pk,sizeof(struct pack));
write_error(ret,cfd,efd);
return 0;
}
//没有将数据从数据库彻底删除,而是将flag改为0
int deal_del_user_request(int cfd,int efd){
int ret;
char name[32];
ret = read(cfd,name,32);
name[ret] = '\0';
read_error(ret,cfd,efd);
struct pack pk;
pk.ver = 1;
pk.type = USER_DEL_OK;
pk.len = 0;
char sql[1024];
int rows = 0;
MYSQL_RES *result = NULL;
sprintf(sql,"select *from user_info where 用户名='%s'",name);
my_go(sql,&result);
rows = mysql_num_rows(result);
if(rows == 0){
pk.type = USER_DEL_FAIL;
ret = write(cfd,&pk,sizeof(struct pack));
write_error(ret,cfd,efd);
return 0;
}
else{
MYSQL_ROW row = NULL;
for(int i=1;i<=rows;i++){
row = mysql_fetch_row(result);
if(strcmp(name,row[1]) == 0){
sprintf(sql,"update user_info set flag=0 where 用户名='%s'",name);
ret = my_go(sql,NULL);
if(ret<0){
pk.type = USER_DEL_FAIL;
}
else{
pk.type = USER_DEL_OK;
sprintf(sql,"root用户admin删除了用户,用户名为[%s]",name);
log_root(sql);
}
break;
}
}
}
//向客户端反馈
ret = write(cfd,&pk,sizeof(struct pack));
write_error(ret,cfd,efd);
return 0;
}
//处理修改用户请求
int deal_mod_user_request(int cfd,int efd){
int ret;
char name[32];
ret = read(cfd,name,32);
name[ret] = '\0';
read_error(ret,cfd,efd);
struct user u2;
struct pack pk;
pk.ver = 1;
pk.type = USER_MOD_OK;
pk.len = 0;
char sql[1024];
int rows = 0;
MYSQL_RES *result = NULL;
sprintf(sql,"select *from user_info where 用户名='%s'",name);
my_go(sql,&result);
rows = mysql_num_rows(result);
if(rows == 0){
pk.type = USER_MOD_FAIL;
ret == write(cfd,&pk,sizeof(struct pack));
write_error(ret,cfd,efd);
return 0;
}
else{
ret = read(cfd,&u2,sizeof(struct user));
read_error(ret,cfd,efd);
sprintf(sql,"update user_info set flag=%d where 用户名='%s'",u2.flag,name);
my_go(sql,NULL);
sprintf(sql,"update user_info set 身份证=%d where 用户名='%s'",u2.iden,name);
my_go(sql,NULL);
sprintf(sql,"update user_info set 职位='%s' where 用户名='%s'",u2.pos,name);
my_go(sql,NULL);
sprintf(sql,"update user_info set 手机号=%d where 用户名='%s'",u2.phone,name);
my_go(sql,NULL);
sprintf(sql,"update user_info set 邮箱='%s' where 用户名='%s'",u2.mail,name);
my_go(sql,NULL);
sprintf(sql,"update user_info set 入职时间='%s' where 用户名='%s'",u2.hiredate,name);
my_go(sql,NULL);
sprintf(sql,"update user_info set 用户名='%s' where 用户名='%s'",u2.name,name);
my_go(sql,NULL);
sprintf(sql,"root用户admin修改了用户[%s]的信息,flag=[%d],身份证=[%d],职位=[%s],手机号=[%d],邮箱=[%s]\
入职时间=[%s],用户名=[%s]",name,u2.flag,u2.iden,u2.pos,u2.phone,u2.mail,u2.hiredate,u2.name);
log_root(sql);
}
ret = write(cfd,&pk,sizeof(struct pack));
write_error(ret,cfd,efd);
return 0;
}
//处理显示所有用户信息请求
int deal_show_user_request(int cfd,int efd){
int ret;
struct user u3;
char sql[1024];
int rows = 0;
MYSQL_RES *result = NULL;
sprintf(sql,"select *from user_info");
my_go(sql,&result);
rows = mysql_num_rows(result);
ret = write(cfd,&rows,sizeof(int));
write_error(ret,cfd,efd);
MYSQL_ROW row = NULL;
for(int i=1;i<=rows;i++){
row = mysql_fetch_row(result);
u3.flag = atoi(row[0]);
strcpy(u3.name,row[1]);
u3.iden = atoi(row[3]);
strcpy(u3.pos,row[4]);
u3.phone = atoi(row[5]);
strcpy(u3.mail,row[6]);
strcpy(u3.hiredate,row[7]);
ret = write(cfd,&u3,sizeof(struct user));
write_error(ret,cfd,efd);
}
return 0;
}
//处理屏幕登录请求
int deal_screen_login_request(int cfd,int efd,struct screen_pk *head){
int ret;
int key = 0;
char number[18];
ret = read(cfd,number,18);
number[ret] = '\0';
read_error(ret,cfd,efd);
struct screen_pk *p = head->next;
struct pack pk;
pk.ver = 1;
pk.type = LOG_OK;
pk.len = 0;
while(p!=NULL){
if(strcmp(p->num,number) == 0){
key = 1;
break;
}
p = p->next;
}
char sql[1024];
int rows = 0;
MYSQL_RES *result = NULL;
sprintf(sql,"select *from screen_info where 序列号='%s'",number);
my_go(sql,&result);
rows = mysql_num_rows(result);
if(rows == 0){
pk.type = LOG_FAIL_NONAME;
}
else if(key == 1){
pk.type = RELOG;
}
else{
MYSQL_ROW row = NULL;
for(int i=1;i<=rows;i++){
row = mysql_fetch_row(result);
int f = atoi(row[0]);
if(strcmp(number,row[1]) == 0&&f == 1){
pk.type = LOG_OK;
sprintf(sql,"屏幕[%s]登录系统",number);
log_user(sql);
struct screen_pk *pnew = NULL;
pnew = create_node1();
pnew->fd = cfd;
strcpy(pnew->num,number);
pnew->next = head->next;
head->next = pnew;
break;
}
else if(strcmp(number,row[1]) == 0&&f == 0){
pk.type = LOG_FLAG0;
break;
}
}
}
ret = write(cfd,&pk,sizeof(struct pack));
write_error(ret,cfd,efd);
}
//处理用户修改密码请求
int deal_mod_pswd_request(int cfd,int efd,struct user_pk *head){
struct user_pk *p = head->next;
int ret;
char pswd[18];
char sql[1024];
char name[32];
while(p!=NULL){
if(p->fd == cfd){
strcpy(name,p->name);
break;
}
p = p->next;
}
ret = read(cfd,pswd,18);
pswd[ret] = '\0';
read_error(ret,cfd,efd);
struct pack pk;
pk.ver = 1;
pk.type = USER_MOD_PSWD_FAIL;
sprintf(sql,"update user_info set 密码='%s' where 用户名='%s'",pswd,name);
ret = my_go(sql,NULL);
if(ret == 0){
pk.type = USER_MOD_PSWD_OK;
sprintf(sql,"用户[%s]修改了密码",name);
log_user(sql);
}
ret = write(cfd,&pk,sizeof(struct pack));
write_error(ret,cfd,efd);
return 0;
}
//处理显示在线屏幕请求
int deal_show_online_screen_request(int cfd,int efd,struct screen_pk *head){
int ret;
struct screen_pk *p = head->next;
struct pack pk;
pk.ver = 1;
pk.type = SHOW_ON;
pk.len = len_screen_list(head);
ret = write(cfd,&pk,sizeof(struct pack));
write_error(ret,cfd,efd);
while(p!=NULL){
ret = write(cfd,p,sizeof(struct screen_pk));
write_error(ret,cfd,efd);
p = p->next;
}
return 0;
}
//处理发送消息请求
int deal_message_request(int cfd,int efd,struct user_pk *head,struct screen_pk *head1){
int ret,objfd;
char number[18];
char name[32];
char buff[1024];
char sql[1024];
ret = read(cfd,number,18);
read_error(ret,cfd,efd);
number[ret] = '\0';
struct pack pk;
pk.ver = 1;
pk.type = MESS_OK;
pk.len = 0;
struct user_pk *t = head->next;
struct screen_pk *p = head1->next;
while(t!=NULL){
if(t->fd == cfd){
strcpy(name,t->name);
break;
}
t = t->next;
}
while(p!=NULL){
if(strcmp(p->num,number) == 0){
objfd = p->fd;
break;
}
p = p->next;
}
ret = read(cfd,buff,1024);
read_error(ret,cfd,efd);
buff[ret] = '\0';
ret = write(objfd,buff,strlen(buff));
if(ret<0){
close(objfd);
pk.type = MESS_FAIL;
}
else{
sprintf(sql,"用户[%s]向屏幕[%s]发送了信息为[%s]的消息",name,number,buff);
log_user(sql);
}
usleep(100000);
ret = write(cfd,&pk,sizeof(struct pack));
write_error(ret,cfd,efd);
return 0;
}
//处理发送文件的请求
int deal_file_request(int cfd,int efd,struct user_pk *head,struct screen_pk *head1){
int ret,rfd,wfd,objfd;
char number[18];
char fname[50];
char buff[1024];
ret = read(cfd,number,18);
read_error(ret,cfd,efd);
number[ret] = '\0';
/* ret = read(cfd,fname,50);
read_error(ret,cfd,efd);
fname[ret] = '\0';
char sql[1024] = "./服务器文件夹/";
char *t = strrchr(fname,'/');
strcpy(sql,t);*/
struct screen_pk *p = head1->next;
while(p!=NULL){
if(strcmp(p->num,number) == 0){
objfd = p->fd;
break;
}
p = p->next;
}
wfd = open("./服务器文件夹/data.txt",O_CREAT|O_WRONLY|O_TRUNC,0777);
if(wfd<0){
perror("open");
return -1;
}
rfd = open("./服务器文件夹/data.txt",O_RDONLY);
if(rfd<0){
perror("open");
return -1;
}
while(1){
ret = read(cfd,buff,1024);
read_error(ret,cfd,efd);
ret = write(wfd,buff,ret);
if(ret<0){
perror("write");
close(wfd);
return -1;
}
ret = read(rfd,buff,1024);
if(ret<0){
perror("read");
close(rfd);
return -1;
}
ret = write(objfd,buff,ret);
write_error(ret,cfd,efd);
}
close(wfd);
close(rfd);
return 0;
}
5)client_request.c
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include "pack.h"
#include "login.h"
#include "list.h"
//读写异常处理函数
static void read_error(int ret,int sockfd){
if(ret<0){
perror("read");
close(sockfd);
exit(-1);
}
else if(ret == 0){
printf("服务器断开连接!\n");
close(sockfd);
exit(-1);
}
}
static void write_error(int ret,int sockfd){
if(ret<0){
perror("write");
close(sockfd);
exit(-1);
}
}
//增加新的屏幕
void add_screen_request(int sockfd){
int ret,flag;
struct screen s1;
while(1){
printf("屏幕是否正在使用(1表示正在使用中,0表示不在使用中):");
scanf("%d",&flag);
while(getchar()!='\n');
if(flag == 1||flag == 0){ //判断输入数字是否为1或0
s1.flag = flag;
break;
}
else{
printf("请输入正确参数!\n");
}
}
printf("序列号:");
scanf("%s",s1.num);
while(getchar()!='\n');
printf("位置:");
scanf("%s",s1.pos);
while(getchar()!='\n');
printf("尺寸:");
scanf("%s",s1.size);
while(getchar()!='\n');
printf("厂商信息:");
scanf("%s",s1.firm);
while(getchar()!='\n');
printf("安装时间:");
scanf("%s",s1.settime);
while(getchar()!='\n');
struct pack *p = NULL;
p = (struct pack*)malloc(sizeof(struct pack)+sizeof(struct screen));
assert(p!=NULL);
p->ver = 1;
p->type = SCR_ADD;//设置type
p->len = sizeof(struct screen);
memcpy(p->data,&s1,sizeof(struct screen));
ret = write(sockfd,p,sizeof(struct pack)+sizeof(struct screen));//发送包头和结构体
write_error(ret,sockfd);
ret = read(sockfd,p,sizeof(struct pack));//读取服务器返回的type
read_error(ret,sockfd);
if(p->type == SCR_ADD_OK){
printf("增加新屏幕成功!\n");
}
else if(p->type == SCR_ADD_FAIL){
printf("增加失败!\n");
}
else{
printf("数据异常!\n");
}
free(p);
return;
}
//删除屏幕
void del_screen_request(int sockfd){
int ret;
char number[18];
printf("请输入需要删除的屏幕的序列号:");
scanf("%s",number);
while(getchar()!='\n');
struct pack pk;
pk.ver = 1;
pk.type = SCR_DEL;//设置type
pk.len = 0;
ret = write(sockfd,&pk,sizeof(struct pack));//发送包给服务器
write_error(ret,sockfd);
ret = write(sockfd,number,strlen(number));//发送序列号给服务器
write_error(ret,sockfd);
usleep(100000);
ret = read(sockfd,&pk,sizeof(struct pack));//读取服务器返回的type
read_error(ret,sockfd);
//判断服务器的返回值
if(pk.type == SCR_DEL_OK){
printf("删除成功!\n");
}
else if(pk.type == SCR_DEL_FAIL){
printf("删除失败!\n");
}
return;
}
//修改屏幕信息
void mod_screen_request(int sockfd){
int ret,flag;
char number[18];
printf("请输入需要修改的屏幕序列号:");
scanf("%s",number);
while(getchar()!='\n');
struct pack pk;
pk.ver = 1;
pk.type = SCR_MOD;//设置type
pk.len = 0;
ret = write(sockfd,&pk,sizeof(struct pack));//发送空包给服务器
write_error(ret,sockfd);
ret = write(sockfd,number,strlen(number));//发送序列号给服务器
write_error(ret,sockfd);
usleep(100000);
ret = read(sockfd,&pk,sizeof(struct pack));//读取服务器返回的type
read_error(ret,sockfd);
if(pk.type == SCR_MOD_FAIL){
printf("无此屏幕!\n");
return;
}
struct screen s2;
while(1){
printf("是否启用该屏幕(1表示启用,0表示不启用):");
scanf("%d",&flag);
while(getchar()!='\n');
if(flag == 1||flag == 0){ //确保修改的flag是0或1
s2.flag = flag;
break;
}
else{
printf("请输入正确参数!\n");
}
}
printf("请输入新的序列号:");
scanf("%s",s2.num);
while(getchar()!='\n');
printf("请输入新的位置:");
scanf("%s",s2.pos);
while(getchar()!='\n');
printf("请输入新的尺寸:");
scanf("%s",s2.size);
while(getchar()!='\n');
printf("请输入新的厂商信息:");
scanf("%s",s2.firm);
while(getchar()!='\n');
printf("请输入新的安装时间:");
scanf("%s",s2.settime);
while(getchar()!='\n');
ret = write(sockfd,&s2,sizeof(struct screen));//将修改后的屏幕结构体发送给服务器
write_error(ret,sockfd);
ret = read(sockfd,&pk,sizeof(struct pack));//读取服务器返回的type
read_error(ret,sockfd);
if(pk.type == SCR_MOD_OK){
printf("修改成功!\n");
}
else if(pk.type == SCR_MOD_FAIL){
printf("修改失败!\n");
}
return;
}
//显示所有屏幕信息
void show_screen_request(int sockfd){
int ret,len;
struct pack pk;
struct screen s3;
pk.ver = 1;
pk.type = SCR_SHOW;//设置type
pk.len = 0;
ret = write(sockfd,&pk,sizeof(struct pack));//将空包发送给服务器
write_error(ret,sockfd);
ret = read(sockfd,&len,sizeof(int));//读取服务器返回的数据库里屏幕个数
read_error(ret,sockfd);
printf("在用/拆除\t序列号\t位置\t尺寸\t厂商信息\t安装时间\n");
while(len){
ret = read(sockfd,&s3,sizeof(struct screen));
read_error(ret,sockfd);
printf("%d\t%s\t%s\t%s\t%s\t%s\n",s3.flag,s3.num,s3.pos,s3.size,s3.firm,s3.settime);
len--;
}
return;
}
//增加新的用户
void add_user_request(int sockfd){
int ret,flag;
struct user u1;
while(1){
printf("用户是否在职(1表示在职,0表示离职):");
scanf("%d",&flag);
while(getchar()!='\n');
if(flag == 1||flag == 0){
u1.flag = flag;
break;
}
else{
printf("请输入正确参数!\n");
}
}
printf("用户名:");
scanf("%s",u1.name);
while(getchar()!='\n');
printf("密码:");
scanf("%s",u1.pswd);
while(getchar()!='\n');
printf("身份证:");
scanf("%d",&u1.iden);
while(getchar()!='\n');
printf("职位:");
scanf("%s",u1.pos);
while(getchar()!='\n');
printf("手机号:");
scanf("%d",&u1.phone);
while(getchar()!='\n');
printf("邮箱:");
scanf("%s",u1.mail);
while(getchar()!='\n');
printf("入职时间:");
scanf("%s",u1.hiredate);
while(getchar()!='\n');
struct pack *p = NULL;
p = (struct pack*)malloc(sizeof(struct pack)+sizeof(struct user));
assert(p!=NULL);
p->ver = 1;
p->type = USER_ADD;//设置type
p->len = sizeof(struct user);
memcpy(p->data,&u1,sizeof(struct user));
ret = write(sockfd,p,sizeof(struct pack)+sizeof(struct user));//将包和用户信息结构体打包发送给服务器
write_error(ret,sockfd);
ret = read(sockfd,p,sizeof(struct pack));//读取服务器返回的type
read_error(ret,sockfd);
if(p->type == USER_ADD_OK){
printf("增加新用户成功!\n");
}
else if(p->type == USER_ADD_FAIL){
printf("增加失败!\n");
}
else{
printf("数据异常!\n");
}
free(p);
return;
}
//删除用户
void del_user_request(int sockfd){
int ret;
char name[32];
printf("请输入需要删除的用户的用户名:");
scanf("%s",name);
while(getchar()!='\n');
struct pack pk;
pk.ver = 1;
pk.type = USER_DEL;//设置type
pk.len = 0;
ret = write(sockfd,&pk,sizeof(struct pack));//发送空包给服务器
write_error(ret,sockfd);
ret = write(sockfd,name,strlen(name));//发送用户名给服务器
write_error(ret,sockfd);
usleep(100000);
ret = read(sockfd,&pk,sizeof(struct pack));//读取服务器返回的type
read_error(ret,sockfd);
//判断服务器的返回值
if(pk.type == USER_DEL_OK){
printf("删除成功!\n");
}
else if(pk.type == USER_DEL_FAIL){
printf("删除失败!\n");
}
return;
}
//修改用户信息
void mod_user_request(int sockfd){
int ret,flag;
char name[32];
printf("请输入需要修改的用户:");
scanf("%s",name);
while(getchar()!='\n');
struct pack pk;
pk.ver = 1;
pk.type = USER_MOD;//设置type
pk.len = 0;
ret = write(sockfd,&pk,sizeof(struct pack));//发送空包给服务器
write_error(ret,sockfd);
ret = write(sockfd,name,strlen(name));//发送用户名给服务器
write_error(ret,sockfd);
usleep(100000);
ret = read(sockfd,&pk,sizeof(struct pack));//读取服务器发送的type
read_error(ret,sockfd);
if(pk.type == USER_MOD_FAIL){
printf("无此用户!\n");
return;
}
struct user u2;
while(1){
printf("该用户是否在职(1表示在职,0表示离职):");
scanf("%d",&flag);
while(getchar()!='\n');
if(flag == 1||flag == 0){
u2.flag = flag;
break;
}
else{
printf("请输入正确参数!\n");
}
}
printf("请输入新的用户名:");
scanf("%s",u2.name);
while(getchar()!='\n');
printf("请输入新的身份证:");
scanf("%d",&u2.iden);
while(getchar()!='\n');
printf("请输入新的职位:");
scanf("%s",u2.pos);
while(getchar()!='\n');
printf("请输入新的手机号:");
scanf("%d",&u2.phone);
while(getchar()!='\n');
printf("请输入新的邮箱:");
scanf("%s",u2.mail);
while(getchar()!='\n');
printf("请输入新的入职时间:");
scanf("%s",u2.hiredate);
while(getchar()!='\n');
ret = write(sockfd,&u2,sizeof(struct user));//将修改后的用户信息结构体发送给服务器
write_error(ret,sockfd);
ret = read(sockfd,&pk,sizeof(struct pack));//读取服务器返回的type
read_error(ret,sockfd);
if(pk.type == USER_MOD_OK){
printf("修改成功!\n");
}
else if(pk.type == USER_MOD_FAIL){
printf("修改失败!\n");
}
return;
}
//显示所有用户信息
void show_user_request(int sockfd){
int ret,len;
struct pack pk;
struct user u3;
pk.ver = 1;
pk.type = USER_SHOW;
pk.len = 0;
ret = write(sockfd,&pk,sizeof(struct pack));
write_error(ret,sockfd);
ret = read(sockfd,&len,sizeof(int));//读取数据库里用户的个数
read_error(ret,sockfd);
printf("在职/离职\t用户名\t身份证\t职位\t手机号\t邮箱\t入职时间\n");
while(len){
ret = read(sockfd,&u3,sizeof(struct user));
read_error(ret,sockfd);
printf("%d\t%s\t%d\t%s\t%d\t%s\t%s\n",u3.flag,u3.name,u3.iden,u3.pos,u3.phone,u3.mail,u3.hiredate);
len--;
}
return;
}
//普通用户修改密码
void mod_pswd_request(int sockfd){
int ret;
struct pack pk;
pk.ver = 1;
pk.type = USER_MOD_PSWD;
pk.len = 0;
ret = write(sockfd,&pk,sizeof(struct pack));
write_error(ret,sockfd);
char pswd[18];
printf("新密码:");
scanf("%s",pswd);
while(getchar()!='\n');
ret = write(sockfd,pswd,strlen(pswd));
write_error(ret,sockfd);
ret = read(sockfd,&pk,sizeof(struct pack));
read_error(ret,sockfd);
if(pk.type == USER_MOD_PSWD_OK){
printf("修改成功!\n");
}
else if(pk.type == USER_MOD_PSWD_FAIL){
printf("修改失败!\n");
}
return;
}
//显示在线屏幕
void show_online_screen(int sockfd){
int ret;
struct screen_pk *head = NULL;
struct pack pk;
pk.ver = 1;
pk.type = SHOW_ON;//设置type
pk.len = 0;
ret = write(sockfd,&pk,sizeof(struct pack));//发送空包给服务器
write_error(ret,sockfd);
ret = read(sockfd,&pk,sizeof(struct pack));//读取在线屏幕的个数
read_error(ret,sockfd);
for(int i=0;i<pk.len;i++){ //将在线屏幕串成链表
struct screen_pk *pnew =NULL;
pnew = create_node1();
ret = read(sockfd,pnew,sizeof(struct screen_pk));//读取在线屏幕的信息
read_error(ret,sockfd);
pnew->next = head;
head = pnew;
}
struct screen_pk *p = head;
printf("当前在线屏幕:\n");
while(p!=NULL){
printf("%s\n",p->num);
p = p->next;
}
free_screen_pk(head);//结束销毁链表
return;
}
//选择屏幕发送消息
void choose_to_message(int sockfd){
char number[18];
char buff[1024];
int ret;
struct pack pk;
pk.ver = 1;
pk.type = MESS;//设置type
pk.len = 0;
ret = write(sockfd,&pk,sizeof(struct pack));//发送空包给服务器
write_error(ret,sockfd);
printf("选择对象屏幕:");
scanf("%s",number);
while(getchar()!='\n');
ret = write(sockfd,number,strlen(number));//发送选择的屏幕序列号
write_error(ret,sockfd);
usleep(100000);
printf("请编辑发送的文字内容:\n");
scanf("%s",buff);
while(getchar()!='\n');
ret = write(sockfd,buff,strlen(buff));//发送编辑的消息
write_error(ret,sockfd);
usleep(100000);
ret = read(sockfd,&pk,sizeof(struct pack));//读取服务器返回的type
read_error(ret,sockfd);
if(pk.type == MESS_OK){
printf("发送成功!\n");
}
else if(pk.type == MESS_FAIL){
printf("发送失败!\n");
}
}
//选择屏幕发送文件
void choose_to_file(int sockfd){
char number[18];
char fname[50];
char buff[1024];
int ret,rfd;
struct pack pk;
pk.ver = 1;
pk.type = SEND_FILE;//设置type
pk.len= 0;
ret = write(sockfd,&pk,sizeof(struct pack));
write_error(ret,sockfd);
printf("选择对象屏幕:");
scanf("%s",number);
while(getchar()!='\n');
ret = write(sockfd,number,strlen(number));
write_error(ret,sockfd);
usleep(100000);
printf("输入发送的文件:\n");
scanf("%s",fname);
while(getchar()!='\n');
/* ret = write(sockfd,fname,strlen(fname));
write_error(ret,sockfd);
usleep(100000);*/
rfd = open(fname,O_RDONLY);//打开文件
if(rfd<0){
perror("open");
exit(-1);
}
while(1){ //每次读1024个字节将整个文件传给服务器
ret = read(rfd,buff,1024);
if(ret<0){
perror("read");
close(rfd);
exit(-1);
}
if(ret == 0){
break;
}
ret = write(sockfd,buff,ret);
write_error(ret,sockfd);
}
close(rfd);
return;
}
6)login.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <string.h>
#include "pack.h"
//将包头信息和root信息打包
struct pack *p = NULL;
p = (struct pack *)malloc(sizeof(struct pack)+sizeof(struct root));
assert(p!=NULL);
p->ver = 1;
p->type = LOG;
p->len = sizeof(struct root);
memcpy(p->data,&r1,sizeof(struct root));
//将打包的信息发送给服务器
ret = write(sockfd,p,sizeof(struct pack)+sizeof(struct root));
if(ret<0){
perror("write");
close(sockfd);
exit(-1);
}
//读取服务器的反馈信息
ret = read(sockfd,p,sizeof(struct pack));
if(ret<0){
perror("read");
close(sockfd);
exit(-1);
}
else if(ret == 0){
printf("服务器断开连接!\n");
close(sockfd);
exit(-1);
}
//判断服务器反馈的type类型
if(p->type == LOG_OK){
printf("登录成功!\n");
return 1;
}
else if(p->type == LOG_FAIL_NONAME){
printf("登录失败,用户名不存在!\n");
}
else if(p->type == LOG_FAIL_WRONGPSWD){
printf("登录失败,密码错误!\n");
}
else{
printf("数据异常!\n");
}
free(p);
return 0;
}
//普通用户密码登录功能
//成功返回1
//失败返回0
int user_login_request(int sockfd){
int ret;
struct root r2;
printf("用户名:");
scanf("%s",r2.name);
while(getchar()!='\n');
printf("密码:");
scanf("%s",r2.pswd);
while(getchar()!='\n');
//将包头信息和root信息打包
struct pack *p = NULL;
p = (struct pack *)malloc(sizeof(struct pack)+sizeof(struct root));
assert(p!=NULL);
p->ver = 1;
p->type = LOG2;
p->len = sizeof(struct root);
memcpy(p->data,&r2,sizeof(struct root));
//将打包的信息发送给服务器
ret = write(sockfd,p,sizeof(struct pack)+sizeof(struct root));
if(ret<0){
perror("write");
close(sockfd);
exit(-1);
}
//读取服务器的反馈信息
ret = read(sockfd,p,sizeof(struct pack));
if(ret<0){
perror("read");
close(sockfd);
exit(-1);
}
else if(ret == 0){
printf("服务器断开连接!\n");
close(sockfd);
exit(-1);
}
//判断服务器反馈的type类型
if(p->type == LOG_OK){
printf("登录成功!\n");
return 1;
}
else if(p->type == LOG_FAIL_NONAME){
printf("登录失败,用户名不存在!\n");
}
else if(p->type == LOG_FAIL_WRONGPSWD){
printf("登录失败,密码错误!\n");
}
else if(p->type == LOG_FLAG0){
printf("您的账户已注销!\n");
}
else{
printf("数据异常!\n");
}
free(p);
return 0;
}
7)log.c
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int log_root(char *str){
int fd,ret;
fd = open("/home/ssw/屏幕推送系统/日志/root.log",O_CREAT|O_APPEND|O_WRONLY,0777);//打开文件
if(fd<0){
return -1;
}
char temp[1024];
time_t tm1;
tm1 = time(NULL);
struct tm *pt = NULL;
pt = localtime(&tm1);
sprintf(temp,"%d年%d月%d日 %d:%d:%d %s\n",pt->tm_year+1900,pt->tm_mon+1,\
pt->tm_mday,pt->tm_hour,pt->tm_min,pt->tm_sec,str);
ret = write(fd,temp,strlen(temp));
if(ret<0){
close(fd);
return -1;
}
close(fd);
return 0;
}
int log_user(char *str){
int fd,ret;
fd = open("/home/ssw/屏幕推送系统/日志/user.log",O_CREAT|O_APPEND|O_WRONLY,0777);
if(fd<0){
return -1;
}
char temp[1024];
time_t tm1;
tm1 = time(NULL);
struct tm *pt = NULL;
pt = localtime(&tm1);
sprintf(temp,"%d年%d月%d日 %d:%d:%d %s\n",pt->tm_year+1900,pt->tm_mon+1,\
pt->tm_mday,pt->tm_hour,pt->tm_min,pt->tm_sec,str);
ret = write(fd,temp,strlen(temp));
if(ret<0){
close(fd);
return -1;
}
close(fd);
return 0;
}
8)mysql.c
#include "./mysql.h"
#include <stdio.h>
#define HOST "localhost"
#define USER "halfgod"
#define PASSWD "1"
#define DB "item_screen"
static MYSQL mysql;
//成功返回0, 失败返回-1
int my_init()
{
//初始化句柄
if(NULL == mysql_init(&mysql))
{
printf("%s\n", mysql_error(&mysql));
return -1;
}
//连接数据库
if(NULL == mysql_real_connect(&mysql, HOST, USER, PASSWD, DB, 0, NULL, 0))
{
printf("%s\n", mysql_error(&mysql));
return -1;
}
mysql_set_character_set(&mysql, "utf8");
return 0;
}
int my_go(char *sql, MYSQL_RES **pres)
{
if(0!= mysql_query(&mysql, sql))
{
printf("%s\n", mysql_error(&mysql));
return -1;
}
MYSQL_RES *result = NULL;
result = mysql_store_result(&mysql);
if(result != NULL)
{
if(pres != NULL)
{
*pres = result;
}
}
return 0;
}
void my_close()
{
mysql_close(&mysql);
}
9)list.c
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "pack.h"
//创建用户结点
struct user_pk *create_node(){
struct user_pk *pnew = NULL;
pnew = (struct user_pk *)malloc(sizeof(struct user_pk));
assert(pnew!=NULL);
pnew->next = NULL;
return pnew;
}
//创建屏幕结点
struct screen_pk *create_node1(){
struct screen_pk *pnew = NULL;
pnew = (struct screen_pk *)malloc(sizeof(struct screen_pk));
assert(pnew!=NULL);
pnew->next = NULL;
return pnew;
}
//释放用户链表
struct user_pk *free_user_pk(struct user_pk *head){
struct user_pk *pdel = NULL;
while(head!=NULL){
pdel = head;
head = head->next;
free(pdel);
}
return head;
}
static struct user_pk *search_user_list(struct user_pk *head,int cfd){
struct user_pk *p = head->next;
while(p!=NULL){
if(p->fd == cfd){
return p;
}
p = p->next;
}
}
//删除用户结点
void del_user_list(struct user_pk *head,int cfd){
struct user_pk *pdel = search_user_list(head,cfd);
struct user_pk *p = head;
while(p->next!=pdel){
p = p->next;
}
p->next = pdel->next;
free(pdel);
}
static struct screen_pk *search_screen_list(struct screen_pk *head,int cfd){
struct screen_pk *p = head->next;
while(p!=NULL){
if(p->fd == cfd){
return p;
}
p = p->next;
}
}
//删除屏幕结点
void del_screen_list(struct screen_pk *head,int cfd){
struct screen_pk *pdel = search_screen_list(head,cfd);
struct screen_pk *p = head;
while(p->next!=pdel){
p = p->next;
}
p->next = pdel->next;
free(pdel);
}
//求屏幕链表长度
int len_screen_list(struct screen_pk *head){
int len = 0;
struct screen_pk *p = head->next;
while(p!=NULL){
len++;
p = p->next;
}
return len;
}
//释放屏幕链表
struct screen_pk *free_screen_pk(struct screen_pk *head){
struct screen_pk *pdel = NULL;
while(head!=NULL){
pdel = head;
head = head->next;
free(pdel);
}
return head;
}
10)menu.c
#include <stdio.h>
void menu1(){
printf("+----------------+\n");
printf("|****用户登录****|\n");
printf("|----------------|\n");
printf("| 1.root用户 |\n");
printf("|----------------|\n");
printf("| 2.普通用户 |\n");
printf("|----------------|\n");
printf("| 0.退出系统 |\n");
printf("+----------------+\n");
printf("请选择:");
}
void menu2(){
printf("+----------------+\n");
printf("|****root用户****|\n");
printf("|----------------|\n");
printf("| 1.管理屏幕 |\n");
printf("|----------------|\n");
printf("| 2.管理用户 |\n");
printf("|----------------|\n");
printf("| 3.查看日志 |\n");
printf("|----------------|\n");
printf("| 0.返回上一层 |\n");
printf("+----------------+\n");
printf("请选择:");
}
void menu3(){
printf("+----------------+\n");
printf("|****管理屏幕****|\n");
printf("|----------------|\n");
printf("| 1.增加新屏幕 |\n");
printf("|----------------|\n");
printf("| 2.删除屏幕 |\n");
printf("|----------------|\n");
printf("| 3.修改屏幕 |\n");
printf("|----------------|\n");
printf("| 4.查看所有屏幕 |\n");
printf("|----------------|\n");
printf("| 0.返回上一层 |\n");
printf("+----------------+\n");
printf("请选择:");
}
void menu4(){
printf("+----------------+\n");
printf("|**管理普通用户**|\n");
printf("|----------------|\n");
printf("| 1.增加新用户 |\n");
printf("|----------------|\n");
printf("| 2.删除用户 |\n");
printf("|----------------|\n");
printf("| 3.修改用户 |\n");
printf("|----------------|\n");
printf("| 4.查看所有用户 |\n");
printf("|----------------|\n");
printf("| 0.返回上一层 |\n");
printf("+----------------+\n");
printf("请选择:");
}
void menu5(){
printf("+------------------+\n");
printf("|*****查看日志*****|\n");
printf("|------------------|\n");
printf("|1.查看root用户日志|\n");
printf("|------------------|\n");
printf("|2.查看普通用户日志|\n");
printf("|------------------|\n");
printf("| 0.返回上一层 |\n");
printf("+------------------+\n");
printf("请选择:");
}
void menu6(){
printf("+------------------+\n");
printf("|*****普通用户*****|\n");
printf("|------------------|\n");
printf("| 1.修改密码 |\n");
printf("|------------------|\n");
printf("| 2.查看在线屏幕 |\n");
printf("|------------------|\n");
printf("|3.选择屏幕发送消息|\n");
printf("|------------------|\n");
printf("|4.选择屏幕发送文件|\n");
printf("|------------------|\n");
printf("| 0.返回上一层 |\n");
printf("+------------------+\n");
printf("请选择:");
}
2. .h文件
1)pack.h
#pragma once
//包头信息
struct pack{
unsigned char ver;
unsigned char type;
unsigned char len;
char data[0];
};
//表示root用户基本信息
struct root{
char name[32];
char pswd[18];
};
//表示普通用户基本信息
struct user{
int flag;
char name[32];
char pswd[18];
int iden;
char pos[32];
int phone;
char mail[32];
char hiredate[32];
};
//表示屏幕基本信息
struct screen{
int flag;
char num[18];
char pos[32];
char size[32];
char firm[32];
char settime[32];
};
struct user_pk{
int fd;
char name[32];
struct user_pk *next;
};
struct screen_pk{
int fd;
char num[18];
struct screen_pk *next;
};
#define LOG 1
#define LOG2 2
#define SCR_LOG 3
#define LOG_OK 4
#define RELOG 5
#define LOG_FLAG0 6
#define LOG_FAIL_NONAME 7
#define LOG_FAIL_WRONGPSWD 8
#define SCR_ADD 9
#define SCR_ADD_OK 10
#define SCR_ADD_FAIL 11
#define SCR_DEL 12
#define SCR_DEL_OK 13
#define SCR_DEL_FAIL 14
#define SCR_MOD 15
#define SCR_MOD_OK 16
#define SCR_MOD_FAIL 17
#define SCR_SHOW 18
#define USER_ADD 19
#define USER_ADD_OK 20
#define USER_ADD_FAIL 21
#define USER_DEL 22
#define USER_DEL_OK 23
#define USER_DEL_FAIL 24
#define USER_MOD 25
#define USER_MOD_OK 26
#define USER_MOD_FAIL 27
#define USER_SHOW 28
#define USER_MOD_PSWD 29
#define USER_MOD_PSWD_OK 30
#define USER_MOD_PSWD_FAIL 31
#define SHOW_ON 32
#define MESS 33
#define MESS_OK 34
#define MESS_FAIL 35
#define SEND_FILE 36
#define SEND_FILE_OK 37
#define SEND_FILE_FAIL 38
2)其他的 .h文件
3.Makefile文件
target: ser cli scr
serobj = mysql.o server.o log.o list.o deal_request.o
cliobj = client.o menu.o login.o list.o client_request.o
scrobj = screen.o
ser:$(serobj)
gcc $^ -o $@ -lmysqlclient
cli:$(cliobj)
gcc $^ -o $@
scr:$(scrobj)
gcc $^ -o $@
%.o : %.c
gcc $^ -o $@ -c
clean:
rm -rf *.o cli ser scr