#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <string.h>
//ssize_t send(int sockfd, const void *buf, size_t len, int flags);
#define A 1 //增加用户
#define D 2 //删除用户
#define M 3 //修改用户信息
#define S 4 //检索用户信息
#define L 5 //登录日志
#define Q 6 //退出
#define N 16
#define R "C_login"
typedef struct
{
int type;//超级用户 普通用户
char name[N];
char data[256]; //password
int com; //命令名
int id; //学号 唯一标识符
int salary;
char address[N];
int age;
int flag;
}MSG;
MSG msg;
void do_adduser(int socketfd,MSG *msg);
void do_delectuser(int socketfd,MSG *msg);
void do_modifyinfo(int socketfd,MSG *msg);
void do_selectinfo(int socketfd,MSG *msg);
void do_selectinfo_self(int socketfd,MSG *msg);
void do_modifyinfo_self(int socketfd,MSG *msg);
void do_selectlogin(int socketfd,MSG *msg);
void do_exit(int socketfd,MSG *msg);
int main(int argc, const char *argv[])
{
int socketfd;
int ret=0;//用来接收超级用户 还是普通用户 1 超级用户 2 普通用户
char s;
struct sockaddr_in server_addr;
if(argc<3)
{
printf("Usage : %s <serv_ip> <serv_port>\n",argv[0]);
exit(-1);
}
if((socketfd=socket(AF_INET,SOCK_STREAM,0))<0)
{
perror("failed to socket");
exit(-1);
}
bzero(&server_addr,sizeof(server_addr));
server_addr.sin_family=AF_INET;
server_addr.sin_addr.s_addr=inet_addr(argv[1]);
server_addr.sin_port = htons(atoi(argv[2]));
if(connect(socketfd,(struct sockaddr *)&server_addr,sizeof(server_addr))<0)
{
perror("failed to connect");
exit(-1);
}
int n;
printf("**************************************\n");
printf(" 欢 迎 访 问 员 工 管 理 系 统 \n");
printf("**************************************\n");
while(1){
printf("请输入用户名:");
if(scanf("%s",msg.name)<=0)
{
perror("scanf");
exit(-1);
}
printf("请输入用户密码:");
if(scanf("%s",msg.data)<=0)
{
perror("scanf");
exit(-1);
}
send(socketfd,&msg,sizeof(MSG),0);
recv(socketfd,&ret,sizeof(ret),0);
if(ret==1)//超级用户
{
while(1)
{
printf("---------------------------------------------------------------------------\n");
printf("--1:添加用户 2:删除用户 3:修改用户信息 4:检索用户信息 5:查询登录日志6:退出----\n");
printf("----------------------------------------------------------------------------\n");
printf("请输入命令:");
scanf("%d",&n);
switch(n)
{
case 1:
do_adduser(socketfd,&msg);
break;
case 2:
do_delectuser(socketfd,&msg);
break;
case 3:
do_modifyinfo(socketfd,&msg);
break;
case 4:
do_selectinfo(socketfd,&msg);
break;
case 5:
do_selectlogin(socketfd,&msg);
break;
case 6:
do_exit(socketfd,&msg);
}
}
}
else if(ret==2)//普通用户
{
while(1)
{
printf("-----------------------------------------------------------------------\n");
printf("-------------1:检索用户信息 2:修改用户信息 3:退出----------------------\n");
printf("-----------------------------------------------------------------------\n");
printf("请输入命令:");
scanf("%d",&n);
switch(n)
{
case 1:
do_selectinfo_self(socketfd,&msg);
break;
case 2:
do_modifyinfo_self(socketfd,&msg);
break;
case 3:
close(socketfd);
exit(0);
}
}
}
else
{
printf("用户名或密码输入错误\n");
printf("重新登录请输入:r 退出请输入:e \n");
getchar();
scanf("%c",&s);
switch(s)
{
case 'r':
break;
case 'e':
return 1;
}
}
}
}
void do_adduser(int socketfd,MSG *msg)
{
int ret=0;
printf("请输入用户名:");
if(scanf("%s",msg->name)<=0)
{
perror("scanf");
exit(-1);
}
printf("请输入密码:");
if(scanf("%s",msg->data)<=0)
{
perror("scanf");
exit(-1);
}
msg->com =A;
msg->type=2; //2代表普通用户,客户端只能添加普通用户,所以写死
printf("请输入你的工资:");
scanf("%d",&(msg->salary));
printf("请输入你的地址:");
scanf("%s",msg->address);
printf("请输入你的年龄:");
scanf("%d",&(msg->age));
send(socketfd,msg,sizeof(MSG),0);
recv(socketfd,&ret,sizeof(ret),0);
if(ret==1)//表示添加成功
{
printf("添加用户成功\n");
}
else
{
printf("添加用户失败\n");
}
}
void do_delectuser(int socketfd,MSG *msg)
{
int ret=0;
printf("请输入你想删除的用户名:");
scanf("%s",msg->name);
printf("请输入你想删除用户名的密码:");
scanf("%s",msg->data);
msg->type=2;
msg->com=D;
send(socketfd,msg,sizeof(MSG),0);
recv(socketfd,&ret,sizeof(ret),0);
if(ret==1)//表示添加成功
{
printf("删除用户成功\n");
}
else
{
printf("删除用户失败\n");
}
}
void do_selectinfo(int socketfd,MSG *msg)
{
int ret=0;
printf("请输入检索的用户:");
scanf("%s",msg->name);
printf("请输入检索用户的密码:");
scanf("%s",msg->data);
do_selectinfo_self(socketfd,msg);
}
void do_modifyinfo(int socketfd,MSG *msg)// 发两次,收两次
{
int ret=0;
int n=0;
printf("请输入你要修改的用户:");
scanf("%s",msg->name);
printf("请输入你要修改用户密码:");
scanf("%s",msg->data);
do_modifyinfo_self(socketfd,msg);
}
void do_selectinfo_self(int socketfd,MSG *msg)
{
msg->type=2;
msg->com=S;
send(socketfd,msg,sizeof(MSG),0);
recv(socketfd,msg,sizeof(MSG),0);
if(msg->flag != 2)
{
printf("编号:%d\n",msg->id);
printf("名字:%s\n",msg->name);
printf("密码:%s\n",msg->data);
printf("年龄:%d\n",msg->age);
printf("工资:%d\n",msg->salary);
}
else
{
printf("没有该用户\n");
}
}
void do_modifyinfo_self(int socketfd,MSG *msg)//发两次 收两次
{
int ret=0;
int n=0;
msg->type=2;
msg->com=M;
send(socketfd,msg,sizeof(MSG),0);//发部分信息
recv(socketfd,msg,sizeof(MSG),0);//收到所有信息
printf("*****************************************\n");
printf(" 你 想 修 改 哪 一 项 \n");
printf(" 1:密 码 2:工 资 3:地 址 4:年 龄\n");
printf("*****************************************\n");
printf("请 选 择: \n");
scanf("%d",&n);
switch(n)
{
case 1:
printf("请输入新密码:");
scanf("%s",msg->data);
break;
case 2:
printf("请输入新工资:");
scanf("%d",&(msg->salary));
break;
case 3:
printf("请输入新地址:");
scanf("%s",msg->address);
break;
case 4:
printf("请输入新年龄:");
scanf("%d",&(msg->age));
break;
}
send(socketfd,msg,sizeof(MSG),0);
recv(socketfd,&ret,sizeof(int),0);
if(ret==1)//表示修改成功
{
printf("修改用户成功\n");
}
else
{
printf("修改用户失败\n");
}
}
void do_selectlogin(int socketfd,MSG *msg)
{
int size;
char str[20]={0};
msg->com = L;
send(socketfd,msg,sizeof(MSG),0);
recv(socketfd,&size,sizeof(int),0);
while(size)
{
int n = recv(socketfd,str,sizeof(str),0);
printf("%s",str);
fflush(stdout);
memset(str,0,sizeof(str));
size -=n;
}
}
void do_exit(int socketfd,MSG *msg)
{
msg->com = Q;
send(socketfd,msg,sizeof(MSG),0);
close(socketfd);
exit(0);
}
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <pthread.h>
#include <time.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#define A 1 //增加
#define D 2 //删除
#define M 3 //修改
#define S 4 //检索
#define L 5 //日志
#define Q 6 //退出
#define N 16
#define R "S_login.txt"
typedef struct {
int type;
char name[16];
char data[256];
int com;
int id;
int salary;
char address[N];
int age;
int flag;
}MSG;
int buf; //标志位
FILE *fp; //数据库文件的额文件指针
FILE *fp1; //临时缓存文件的文件流指针
FILE *fp2; //用户登录日志的文件流指针
int id = 1; //员工编号
MSG user,tmp,linshi;
void *myrutine(void *arg);
int record(MSG *msg,int symbol);
int main(int argc,const char *argv[])
{
printf("*******等待用户访问*******\n");
if((fp = fopen("mydata.db","a+")) == NULL)
{
perror("fail to fopen 44");
return -1;
}
MSG root ={
.type = 1,
.name = "admin",
.data = "123456",
};
if(fread(&tmp,sizeof(MSG),1,fp) != 1)
{
fwrite(&root,sizeof(MSG),1,fp);
fclose(fp);
}
else
{
fclose(fp);
}
int sockfd,clientfd;
if((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1)
{
perror("fail to socket");
exit(-1);
}
int on = 1;
setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(int));
struct sockaddr_in serveraddr = {
.sin_family = AF_INET,
.sin_addr.s_addr = INADDR_ANY,
.sin_port = htons( 8888 ),
}, clientaddr={0};
int len = sizeof(serveraddr);
if(-1 == bind(sockfd, (struct sockaddr*)&serveraddr, len) )
{
perror("bind");
return -1;
}
listen(sockfd, 10);
char buf[100];
while(1)
{
if(-1 == (clientfd = accept(sockfd, (struct sockaddr*)&clientaddr, &len) ) )
{
perror("accept");
return -1;
}
printf("IP: %s connected !\n", inet_ntoa(clientaddr.sin_addr) );
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_t tid;
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
pthread_create(&tid,&attr, myrutine, (void*)clientfd);
printf("thread runing...........\n");
}
close(sockfd);
fclose(fp);
exit(0);
}
void *myrutine(void *arg)
{
int clientfd = (int)arg;
while(1)
{
read(clientfd,&user,sizeof(user));//读取客户端发过来的数据放到user结构体中
if((fp = fopen("mydata.db","a+")) == NULL)
{
perror("fail to fopen mydata.db");
return (void *)-1;
}
fseek(fp,0,SEEK_SET);
#if 1
while(fread(&tmp,sizeof(MSG),1,fp))//把文件中的结构体读出来放到tmp结构体中
{
if((!strcmp(tmp.name,user.name)) && (!strcmp(tmp.data,user.data)))
{
if(tmp.type == 1)
{
buf = tmp.type;
write(clientfd,&buf,sizeof(int));
printf("超级用户登录成功\n");
record(&user,buf);
}
if(tmp.type == 2)
{
buf = tmp.type;
write(clientfd,&buf,sizeof(int));
printf("普通用户登录成功\n");
record(&user,buf);
}
fclose(fp);
goto aa;
}
}
buf = 3; //用户名或密码输入错误
write(clientfd,&buf,sizeof(int));
fclose(fp);
record(&user,buf);
continue;
}
#endif
aa:
while(1)
{
struct stat s;
if((fp = fopen("mydata.db","a+")) == NULL)
{
perror("fail to fopen");
return (void *)-1;
}
read(clientfd,&user,sizeof(user));
switch(user.com)
{
case A:
fseek(fp,0,SEEK_END);
user.id = id;
id++;
if(fwrite(&user,sizeof(MSG),1,fp) > 0)
{
fflush(fp);
buf = 1;
write(clientfd,&buf,sizeof(int));
printf("添加用户成功\n");
}
else
{
buf = 2;
write(clientfd,&buf,sizeof(int));
printf("添加用户失败\n");
}
fclose(fp);
break;
case M:
#if 1
//fseek(fp,0,SEEK_SET);
while(fread(&tmp,sizeof(MSG),1,fp))
{
if((!strcmp(user.name,tmp.name))&&(!strcmp(user.data,tmp.data)))
{
write(clientfd,&tmp,sizeof(tmp));
printf("成功发送用户信息给客户端\n");
break;
}
}
fclose(fp);
read(clientfd,&user,sizeof(user));//等待客户端修改后的信息
if((fp1 = fopen("buf.db","w+")) == NULL)
{
perror("fail to fopen");
return (void *)-1;
}
if((fp = fopen("mydata.db","a+")) == NULL)
{
perror("fail to fopen");
return (void *)-1;
}
while(fread(&tmp,sizeof(MSG),1,fp))
{
if((!strcmp(user.name,tmp.name))&&(user.id == tmp.id))
{
fwrite(&user,sizeof(MSG),1,fp1);
fflush(fp1);
continue;
}
fwrite(&tmp,sizeof(MSG),1,fp1);
fflush(fp1);
}
fclose(fp);
if((fp = fopen("mydata.db","w+")) == NULL)
{
perror("fail to fopen");
return (void *)-1;
}
fseek(fp1,0,SEEK_SET);
while(fread(&tmp,sizeof(MSG),1,fp1))
{
fwrite(&tmp,sizeof(MSG),1,fp);
fflush(fp);
}
fclose(fp);
fclose(fp1);
buf = 1;
write(clientfd,&buf,sizeof(buf));
printf("修改成功\n");
break;
#endif
case D:
#if 1
if((fp1 = fopen("buf.db","w+")) == NULL)
{
perror("fail to fopen");
return (void *)-1;
}
while(fread(&tmp,sizeof(MSG),1,fp))
{
if((!strcmp(user.name,tmp.name))&&(!strcmp(user.data,tmp.data)))
{
continue;
}
fwrite(&tmp,sizeof(MSG),1,fp1);
fflush(fp1);
}
fclose(fp);
if((fp = fopen("mydata.db","w+")) == NULL)
{
perror("fail to fopen");
return (void *)-1;
}
fseek(fp1,0,SEEK_SET);
while(fread(&tmp,sizeof(MSG),1,fp1))
{
fwrite(&tmp,sizeof(MSG),1,fp);
fflush(fp);
}
fflush(fp);
fclose(fp);
fclose(fp1);
buf = 1;
write(clientfd,&buf,sizeof(buf));
printf("删除成功\n");
#endif
break;
case S:
fseek(fp,0,SEEK_SET);
while(fread(&tmp,sizeof(MSG),1,fp))
{
if((!strcmp(user.name,tmp.name))&&(!strcmp(user.data,tmp.data)))
{
write(clientfd,&tmp,sizeof(tmp));
printf("成功检索到用户信息\n");
fclose(fp);
goto aa;
}
}
fclose(fp);
linshi.flag = 2; //2表示检索失败,重新输入用户名和密码
write(clientfd,&linshi,sizeof(MSG));
break;
case L:
stat(R,&s);
buf = s.st_size;
write(clientfd,&buf,sizeof(buf));
int n;
char str[20]={0};
int fd = open(R,O_RDONLY);
while(n = read(fd,str,sizeof(str)))
{
write(clientfd,str,n);
memset(str,0,sizeof(str));
}
close(fd);
break;
case Q:
printf("用户退出\n");
close(clientfd);
return (void *)0;
}
}
}
int record(MSG *msg,int symbol)
{
if((fp2 = fopen(R,"a+")) == NULL)
{
perror("fail to fopen login.log");
return -1;
}
time_t tv;
tv = time(NULL);
if(symbol == 3)
{
fprintf(fp2,"%s 登录失败 %s",msg->name,ctime(&tv));
}
else
{
fprintf(fp2,"%s 登录成功 %s",msg->name,ctime(&tv));
}
fflush(fp2);
fclose(fp2);
return 0;
}