C语言小项目-----员工管理系统

目录

项目要求:

考虑点:

 实现过程

所用知识点

最终效果如下:


项目要求:

 

考虑点:

服务器端用select监听多个客户端,考虑点在于,公司内部的系统管理系统,不会有太多人每天都登陆,监听1024-4个客户端是够用的,(0,1,2,3被占用)

select会把所有建立连接的套接字都放到一个链表里,当某个套接字(文件描述符)有事件就会留在这个集合中,进行一步步的处理,代码在下面---->

 实现过程

1.服务器端先创建员工数据库,包含两张表(员工表,历史记录表)

2.要建立通信

3.使用io多路复用(select)实现客户端服务器的交互传输(登陆,添加,删除.....)

将每个功能函数进行封装,并且每个功能函数中都要调用历史记录的插入函数,这样历史记录表中才能有数据。

所用知识点

1.tcp/ip 通信的建立过程(套接字,绑定,监听,收发数据)

2.并发服务器---多种方式可实现(多进程,多线程,io多路复用)

3.数据库接口的使用

4.函数封装,结构体传参。代码编写逻辑,每一个功能分步实现。

最终效果如下:

 登陆界面:

 修改:

 删除:

 添加

 查询历史记录

 总结

代码编写过程中遇到不少bug,一开始的思路和扎实的基础相当重要,

遇到错误首先要针对性排查,知道错因

编写代码要条例清晰,一个功能一个功能的实现,每实现一个测试一下,理清思路很重要,毕竟代码相当抽象。

#include <stdio.h>
#include "yg.h"
int updateMaxfd(int maxfd, fd_set readfds);
sqlite3 *create_sqlitedb(void);
int do_login(int sfd, MSG *msg, sqlite3 *db); // 登陆
int ser_add(int sfd, MSG *msgser, sqlite3 *db);
int select_by_name(int sensfd, MSG *msgser, sqlite3 *db);
int select_all(int sensfd, MSG *msgser, sqlite3 *db);
int Change_ser(int sensfd, MSG *msg_ser, sqlite3 *db);
int delete_ser(int sensfd, MSG *msgser, sqlite3 *db);
int history_ser(int sensfd, MSG *msgser, sqlite3 *db);
void insert_history(sqlite3 *db,char *name,char *opera);
//接收发送
void send_recv(int sfd, MSG *msg);
int main(int argc, char const *argv[])
{
    // 打开数据库,创建2张表
    sqlite3 *db;
    db = create_sqlitedb();
    int sfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sfd < 0)
    {
        ERR("socket failed");
        return -1;
    }
    printf("创建套接字成功\n");
    int reuse = 1;
    if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
    {
        ERR("setsockopt failed");
        return -1;
    }

    struct sockaddr_in sin; // 地址族
    sin.sin_family = AF_INET;
    sin.sin_port = htons(PORT);
    sin.sin_addr.s_addr = inet_addr(IP);
    if (bind(sfd, (struct sockaddr *)&sin, sizeof(sin)) < 0)
    {
        ERR("bind failed");
        return -1;
    }
    printf("绑定成功\n");
    if (listen(sfd, 10) < 0)
    {
        ERR("listen");
        return -1;
    }
    printf("监听设置成功\n");
    fd_set readfds, tempfds;
    // 清空读集合
    FD_ZERO(&readfds);
    FD_ZERO(&tempfds);
    // 把需要的文件描述符放到读集合中
    FD_SET(0, &readfds);
    FD_SET(sfd, &readfds);
    int maxfd = sfd;
    int se;             // 接收select函数返回值
    char buf[128] = ""; // 存放客户端发来的信息
    MSG msgcli;         // 结构体存放客户端发来的消息
    ssize_t res = 0;
    int newfd = 0;
    // 定义数组存储客户端的地址信息结构体,客户端不会再有012sfd4个去掉
    struct sockaddr_in cinaddr[1024 - 4];
    struct sockaddr_in cin; // cin存放客户端的IP端口
    socklen_t cinlen = sizeof(cin);
    int i = 0;
    while (1)
    {
        tempfds = readfds;
        se = select(maxfd + 1, &tempfds, NULL, NULL, NULL);
        if (se < 0)
        {
            ERR("select failed");
            return -1;
        }
        else if (0 == se)
        {
            printf("time out\n");
            break;
        }
        // 此时有事件发生,判断哪个文件描述符有事件触发
        for (i = 0; i <= maxfd && se != 0; i++)
        {
            // 对监听到的文件描述符做判断
            if (FD_ISSET(i, &tempfds))
            {
                // 该文件描述符在集合中,执行操作
                se--; // 当se==0就绪个数处理完成
                if (0 == i)
                {
                    // 向客户端发送消息
                    int sendfd;
                    bzero(&msg, sizeof(MSG));
                    res = scanf("%d %s", &sendfd, buf);
                    while (getchar() != 10)
                        ;
                    printf("sendfd=%d %s\n", sendfd, buf);
                    if (res != 2)
                    {
                        fprintf(stderr, "请输入正确的格式:fd string\n");
                        continue;
                    }
                    if (sendfd <= 3 || FD_ISSET(sendfd, &readfds) == 0)
                    {
                        fprintf(stderr, "输入文件描述符有误%d\n", sendfd);
                        continue;
                    }
                    if (send(sendfd, buf, sizeof(buf), 0) < 0)
                    {
                        ERR("send");
                        return -1;
                    }
                    printf("发送成功\n");
                }
                else if (sfd == i)
                {
                    // 客户端连接
                    newfd = accept(sfd, (struct sockaddr *)&cin, &cinlen);
                    if (newfd < 0)
                    {
                        ERR("accept");
                        return -1;
                    }
                    // 连接成功
                    printf("[%s:%d] newfd=%d客户端连接成功\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), newfd);
                    // 将客户端的地址信息结构体转存到数组中
                    cinaddr[newfd - 4] = cin;
                    // 将新连接的newfd添加到readfds集合中
                    FD_SET(newfd, &readfds);
                    // 更新maxfd
                    maxfd = maxfd > newfd ? maxfd : newfd;
                }
                else
                {

                    // 客户端交互
                    bzero(msg, sizeof(MSG));
                    // i连接成功的文件描述符
                    // 接收到的消息放到msgcli结构体中
                    // printf("yes\n");
                    res = recv(i, msg, sizeof(MSG), 0);
                    if (res < 0)
                    {
                        ERR("recv");
                        return -1;
                    }
                    else if (0 == res)
                    {
                        fprintf(stderr, "[%s:%d] newfd=%d客户端关闭\n", inet_ntoa(cinaddr[i - 4].sin_addr), ntohs(cinaddr[i - 4].sin_port), i);
                        printf("%s\n", buf);
                        close(i); // 关闭不需要的文件描述符
                        FD_CLR(i, &readfds);
                        maxfd = updateMaxfd(maxfd, readfds);
                    }
                    else
                    {
                        // res>0收到客户端的消息----做相应处理
                        fprintf(stderr, "[%s:%d] newfd=%d客户\n", inet_ntoa(cinaddr[i - 4].sin_addr), ntohs(cinaddr[i - 4].sin_port), i);
                        char type = msg->msgtype;
                        switch (type)
                        {
                        case 'L': // 登陆
                            do_login(i, msg, db);
                            break;
                        case 'u': // 登陆
                            printf("%c\n", msg->msgtype);
                            if(msg->info.usertype=='u')
                            {
                                do_login(i, msg, db);
                            }
                            break;
                        case 'A':
                            ser_add(i, msg, db);
                            break;
                        case 'F':
                            //人名查找
                            select_by_name(i,msg,db);
                            break;
                        case 's':
                            select_all(i,msg,db);
                            break;
                        case 'C':
                        //修改
                            Change_ser(i,msg,db);    
                            break;
                        case 'D':
                        //删除
                            delete_ser(i,msg,db);
                            break;
                        case 'H':
                            history_ser(i,msg,db);
                            break;
                        }
                    }
                }
            }
        }
    }
    close(sfd);
    return 0;
}

// 查询历史记录
int history_ser(int sensfd, MSG *msgser, sqlite3 *db)
{
    char sql[] = "select * from history"; // 存放数据库查询语句
    char **pres = NULL; // 存放数据库查询到的首地址
    int row,column,i,j,k=0;
    insert_history(db,msgser->info.name,sql);
    bzero(msgser->recvmsg,sizeof(msgser->recvmsg));
    if (sqlite3_get_table(db, sql, &pres, &row, &column, NULL) != 0)
    {       
        //用户名密码错误
        ERR_sqlite3(db);
        return -1;
    }else if(0==row)
    {   //
        sprintf(msgser->recvmsg,"没有记录");
        exit -1;
    }else{
        
        for(i=0;i<=row;i++)
        { 
            for(j=0;j<column;j++)
            {
                sprintf(msgser->recvmsg+strlen(msgser->recvmsg),"%s\t",pres[k++]); 
            }
            strcat(msgser->recvmsg,"\n");
        }
       
    }
    if(send(sensfd, msgser, sizeof(MSG), 0) < 0)
    {
        ERR("send");
        return -1;
    }
    printf("返回历史记录\n");
    printf("%s\n",msg->recvmsg);
    return 0;
}
//向历史记录表插入数据
void insert_history(sqlite3 *db,char *name,char *opera)
{
    char sql[256]="";
    char* errmsg = NULL;
    char l_time[32] = "";
	time_t t = time(NULL);
    //info指向获取当前时间的地址
	struct tm* info = localtime(&t);
	sprintf(l_time, "%d-%02d-%02d %02d:%02d",info->tm_year+1900, info->tm_mon+1, info->tm_mday,\
			info->tm_hour, info->tm_min);

	bzero(sql, sizeof(sql));
	sprintf(sql, "insert into history values(\"%s\", \"%s\", \"%s\")", \
			 l_time,name,opera);
	//printf("sql = %s %d\n", sql, __LINE__);

	if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != 0)
	{
		ERR_sqlite3(db);
		return ;
	}
	printf("插入历史记录成功\n");
    return ;
}

// 退出---
// 删除信息
int delete_ser(int sensfd, MSG *msgser, sqlite3 *db)
{
    char sql[128]="";
    char *errmsg=NULL;

    sprintf(sql,"delete from yginfo where name=\"%s\";",msgser->info.name);
    if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
    {
        ERR_sqlite3(db);
        return -1;
    }
    //删除成功--反馈给客户端
    bzero(msg,sizeof(MSG));
    sprintf(msgser->recvmsg,"%s删除成功",msgser->info.name);
    if(send(sensfd,msgser,sizeof(MSG),0)>0)
    {
        printf("删除成功\n");
    }
    insert_history(db,msgser->info.name,msgser->recvmsg);

}
// 修改员工信息
int Change_ser(int sensfd, MSG *msg_ser, sqlite3 *db)
{   
    MSG chan_info;//此结构体用来接收要修改的信息
    char sql[128]="";
    char *errmsg=NULL;
    char name[30]="";
    strcpy(name,msg_ser->info.name);//插入到历史记录表中
    //判断要修改员工在不在数据库中
    select_by_name(sensfd,msg_ser,db);
    //接收要修改的字段
    if(recv(sensfd,&chan_info,sizeof(chan_info),0)>0)
    {
    switch(chan_info.msgtype)
    {
    case '1':
		//修改年龄
        bzero(sql,sizeof(sql));

		sprintf(sql,"update yginfo set age=%d where name=\"%s\";",chan_info.info.age,msg_ser->info.name);
        if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
        {
            ERR_sqlite3(db);
            return -1;
        }
        //修改成功--反馈给客户端
        bzero(&chan_info,sizeof(MSG));
        strcpy(chan_info.recvmsg,"年龄修改成功");
        if(send(sensfd,&chan_info,sizeof(chan_info),0)>0)
        {
            printf("年龄修改成功\n");
        }
        insert_history(db,name,chan_info.recvmsg);
		break;
	case '2':
		//修改性别>>");
		bzero(sql,sizeof(sql));
        sprintf(sql,"update yginfo set sex=\"%s\" where name=\"%s\";",chan_info.info.sex,msg_ser->info.name);
        if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
        {
            ERR_sqlite3(db);
            return -1;
        }
        //修改成功--反馈给客户端
        strcpy(chan_info.recvmsg,"性别修改成功");
        if(send(sensfd,&chan_info,sizeof(chan_info),0)>0)
        {
            printf("性别修改成功\n");
        }
        insert_history(db,name,chan_info.recvmsg);
		break;
	case '3':
		//修改手机号>>");
		bzero(sql,sizeof(sql));
        sprintf(sql,"update yginfo set tel=\"%s\" where name=\"%s\";",chan_info.info.tel,msg_ser->info.name);
        if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
        {
            ERR_sqlite3(db);
            return -1;
        }
        //修改成功--反馈给客户端
        strcpy(chan_info.recvmsg,"手机号修改成功");
        if(send(sensfd,&chan_info,sizeof(chan_info),0)>0)
        {
            printf("手机号修改成功\n");
        }
        insert_history(db,name,chan_info.recvmsg);
		break;
	case '4':
		//修改密码
        bzero(sql,sizeof(sql));
        sprintf(sql,"update yginfo set passwd=\"%s\" where name=\"%s\";",chan_info.info.passwd,msg_ser->info.name);
        if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
        {
            ERR_sqlite3(db);
            return -1;
        }
        //修改成功--反馈给客户端
        strcpy(chan_info.recvmsg,"密码修改成功");
        if(send(sensfd,&chan_info,sizeof(chan_info),0)>0)
        {
            printf("密码修改成功\n");
        }
        insert_history(db,name,chan_info.recvmsg);
		break;
	case '5':
		//修改家庭住址>>");
        bzero(sql,sizeof(sql));
        sprintf(sql,"update yginfo set addr=\"%s\" where name=\"%s\";",chan_info.info.addr,msg_ser->info.name);
        if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
        {
            ERR_sqlite3(db);
            return -1;
        }
        //修改成功--反馈给客户端
        strcpy(chan_info.recvmsg,"家庭住址修改成功");
        if(send(sensfd,&chan_info,sizeof(chan_info),0)>0)
        {
            printf("家庭住址修改成功\n");
        }
        insert_history(db,name,chan_info.recvmsg);
		break;
	case '6':
		//修改职位>>");
        bzero(sql,sizeof(sql));
        sprintf(sql,"update yginfo set work=\"%s\" where name=\"%s\";",chan_info.info.work,msg_ser->info.name);
        if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
        {
            ERR_sqlite3(db);
            return -1;
        }
        //修改成功--反馈给客户端
        strcpy(chan_info.recvmsg,"职位修改成功");
        if(send(sensfd,&chan_info,sizeof(chan_info),0)>0)
        {
            printf("职位修改成功\n");
        }
        insert_history(db,name,chan_info.recvmsg);
		break;
	case '7':
		//修改入职日期(格式2022.10.10)>>");
        bzero(sql,sizeof(sql));
        sprintf(sql,"update yginfo set date=\"%s\" where name=\"%s\";",chan_info.info.date,msg_ser->info.name);
        if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
        {
            ERR_sqlite3(db);
            return -1;
        }
        //修改成功--反馈给客户端
        strcpy(chan_info.recvmsg,"入职日期修改成功");
        if(send(sensfd,&chan_info,sizeof(chan_info),0)>0)
        {
            printf("入职日期修改成功\n");
        }
        insert_history(db,name,chan_info.recvmsg);
		break;
	}
    }
    return 0;
}
//发送接收
void send_recv(int sfd, MSG *msg)
{
	int res;
    bzero(msg, sizeof(MSG));
	if (send(sfd, msg, sizeof(MSG), 0) < 0)
	{
		ERR("send");
		exit;
	}
	printf("send success\n");
	bzero(msg, sizeof(MSG));
	res = recv(sfd, msg, sizeof(MSG), 0);
	if (res < 0)
	{
		ERR("recv");
		printf("接收失败\n");
		exit;
	}
	else if (0 == res)
	{
		fprintf(stderr, "服务器关闭\n");
		exit;
	}
	printf("接收成功\n");
	return ;
}
//查找所有
int select_all(int sensfd, MSG *msgser, sqlite3 *db)
{
    char sql[] = "select * from yginfo"; // 存放数据库查询语句
    char **pres = NULL; // 存放数据库查询到的首地址
    int row,column,i,j,k=0;
    bzero(msg->recvmsg,sizeof(msg->recvmsg));
    if (sqlite3_get_table(db, sql, &pres, &row, &column, NULL) != 0)
    {
        // 用户名密码错误
        sprintf(msg->recvmsg,"没有员工"); 
        ERR_sqlite3(db);
        return -1;
    }else{
        
        for(i=0;i<=row;i++)
        {
            printf("row=%d,column=%d\n",row,column);
            for(j=0;j<column;j++)
            {
                sprintf(msg->recvmsg+strlen(msg->recvmsg),"%s\t",pres[k++]); 
            }
            strcat(msg->recvmsg,"\n");
        }
       
    }
    if (send(sensfd, msg, sizeof(MSG), 0) < 0)
    {
        ERR("send");
        return -1;
    }
    insert_history(db,msgser->info.name,msg->recvmsg);

}
// 查询信息
int select_by_name(int sensfd, MSG *msgser, sqlite3 *db)
{
    char sql[128] = ""; // 存放数据库查询语句
    char **pres = NULL; // 存放数据库查询到的首地址
    int row,column,i,j,k=0;
    bzero(msg->recvmsg,sizeof(msg->recvmsg));
    sprintf(sql, "select * from yginfo where name=\"%s\";", msg->info.name);
    if (sqlite3_get_table(db, sql, &pres, &row, &column, NULL) != 0)
    {
        //函数执行失败 
        ERR_sqlite3(db);
        return -1;
    }else if(0==row){
        //未找到----用户名密码错误
        sprintf(msg->recvmsg,"没有这个员工");
        msg->msgtype='N';//未找到
    }else{    
        for(i=0;i<=row;i++)
        {
            printf("row=%d,column=%d\n",row,column);
            for(j=0;j<column;j++)
            {
                sprintf(msg->recvmsg+strlen(msg->recvmsg),"%s\t",pres[k++]); 
            }
            strcat(msg->recvmsg,"\n");
        }
        msg->msgtype='O';//成功找到   
    }
    if (send(sensfd, msg, sizeof(MSG), 0) < 0)
    {
        ERR("send");
        return -1;
    }
    insert_history(db,msgser->info.name,msg->recvmsg);
    if(0==row)
    {
        return -1;
    }else return 0;
}
// 登陆
int do_login(int sfd, MSG *msg, sqlite3 *db)
{
    char sql[128] = ""; // 存放数据库查询语句
    char **pres = NULL; // 存放数据库查询到的首地址
    sprintf(sql, "select * from yginfo where name=\"%s\" and passwd=\"%s\";", msg->info.name, msg->info.passwd);
    printf("%s\n", sql);
    if (sqlite3_get_table(db, sql, &pres, NULL, NULL, NULL) != 0)
    {
        // 用户名密码错误
        printf("用户名或密码错误\n");
        ERR_sqlite3(db);
        return -1;
    }
    else
    {
        // 可以登陆
        bzero(msg, sizeof(MSG));
        strcpy(msg->recvmsg, "login_ok");
    }
    // 给客户端传递可登陆信号 
    if (send(sfd, msg, sizeof(MSG), 0) < 0)
    {
        ERR("send");
        return -1;
    }
    insert_history(db,msg->info.name,msg->recvmsg);
    printf("可登陆,发送成功\n");
    return 0;
}
// 更新select文件描述符
int updateMaxfd(int maxfd, fd_set readfds)
{
    for (int j = maxfd; j >= 0; j--)
    {
        if (FD_ISSET(j, &readfds))
        {
            return j;
        }
    }
    return 0;
}
sqlite3 *create_sqlitedb(void)
{
    sqlite3 *db;
    char *errmsg = NULL; // 指向错误信息的地址
    if (sqlite3_open("./yuangong.db", &db) != SQLITE_OK)
    {

        ERR_sqlite3(db);
        return NULL;
    }
    printf("数据库创建成功\n");
    // 创建员工信息表
    char sql[128] = "create table if not exists yginfo(name char,age int,sex char,work char,tel char,addr char,passwd char,date char,usertype char)";
    if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
    {
        ERR_sqlite3(db);
        return NULL;
    }
    printf("员工表创建成功\n");
    // 创建历史记录表
    sprintf(sql, "create table if not exists history(time char,name char,opera char)");
    if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
    {
        ERR_sqlite3(db);
        return NULL;
    }
    printf("历史记录表创建成功\n");
    return db;
}
// 添加员工信息
int ser_add(int sfd, MSG *msg, sqlite3 *db)
{

    int ret_value = 0;
    char *errmsg = NULL;
    char sql[512] = "";
    sprintf(sql, "insert into yginfo values(\"%s\", %d,\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",%c);", msg->info.name,msg->info.age, msg->info.sex, msg->info.work, msg->info.tel, msg->info.addr, msg->info.passwd, msg->info.date,msg->info.usertype);
    printf("%s", sql);
    if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != 0)
    {
        printf("sqlite3_exec:%s %d\n", errmsg, __LINE__);
        strcpy(msg->recvmsg, "插入失败");
        ret_value = -1;
    }
    else
    {
        printf("添加成功\n");
        strcpy(msg->recvmsg, "添加成功");
    }
    if (send(sfd, msg, sizeof(MSG), 0) < 0)
    {
        ERR("send");
        ret_value = -1;
    }
    insert_history(db,msg->info.name,msg->recvmsg);
    return ret_value;
}

客户端

#include "yg.h"
int init_inet(void); //网络初始化
void send_recv(int sfd, MSG *msg);//接收发送
int do_login(int sfd);//登陆
int root_login(int sfd,MSG *msg);//管理员登陆
int root_menu(int sfd);//管理员登陆界面
int user_login(int sfd,MSG *msg);//普通用户登陆
// root用户功能函数
int Select_fun(int sfd);//查询
int Change_fun(int sfd);//修改
void change_by_name(int sfd);//查找名字修改
int Add_fun(int sfd);//添加
int Delete_fun(int sfd);//删除
int History(int sfd);//历史记录

//普通用户功能函数

int main(int argc, const char *argv[])
{
	int sfd = init_inet(); //连接服务器
	while (1)
	{
		//system("clear");
		printf("****************\n");
		printf("*****1.登录*****\n");
		printf("*****2.退出*****\n");
		printf("****************\n");
		scanf("%c", &choose);
		while (getchar() != 10);
		switch (choose)
		{
		case '1':
			msg->msgtype='L';
			do_login(sfd);
			break;
		case '2':
			close(sfd);
			exit(0);
		}
	}

	close(sfd);
	return 0;
}
int do_login(int sfd)
{
	while (1)
	{
		printf("******0.管理员root********\n");
		printf("******1.普通员工user******\n");
		printf("******2.退出     *********\n");
		printf("按数字键选择>>");
		scanf("%c", &choose);
		while(getchar()!=10);
		switch (choose)
		{
		case '0':
			msg->info.usertype='L';
			root_login(sfd,msg);
			break;
		case '1':
			msg->info.usertype='U';
			user_login(sfd,msg);
			break;
		case '2':
			exit(-1);
		}
	}
	return 0;
}

int root_menu(int sfd)
{
	int flag = 0; //返回上级标志位
	char a;

	while (1)
	{
		if (flag == 1)
		{
			break;
		}
		system("clear");
		printf("******1.查询*******\n");
		printf("******2.修改*******\n");
		printf("******3.添加*******\n");
		printf("******4.删除*******\n");
		printf("******5.历史记录****\n");
		printf("******6.退出********\n");
		printf("*****按数字键选择*****\n");
		scanf("%c", &a);
		while(getchar()!=10);
		switch (a)
		{
		case '1':
			Select_fun(sfd);
			break;
		case '2':
			Change_fun(sfd);
			break;
		case '3':
			Add_fun(sfd);
			break;
		case '4':
			Delete_fun(sfd);
			break;
		case '5':
			History(sfd);
			break;
		case '6':
			flag = 1;
			break;
		}
	}
	return 0;
}
int Change_fun(int sfd)
{	
	msg->msgtype='C';
	printf("请输入要修改的用户名>>");
	scanf("%s", msg->info.name);
	while(getchar()!=10);
	if (send(sfd, msg, sizeof(MSG), 0) < 0)
	{
		ERR("send");
		return -1;
	}
	printf("要修改的用户名%s", msg->info.name);
	printf("send success---------\n");
	bzero(msg, sizeof(MSG));
	res = recv(sfd, msg, sizeof(MSG), 0);
	if (res < 0)
	{
		ERR("recv");
		return -1;
	}
	else if (0 == res)
	{
		fprintf(stderr, "服务器关闭\n");
		return -1;
	}
	if(strcmp(msg->recvmsg, "没有这个员工")==0)
	{ //用户不存在
		printf("没有这个员工>>");
	}else if(msg->msgtype='O')
	{
		change_by_name(sfd); //发送要修改的字段
	}
	return 0;
}
//根据名字修改某字段
void change_by_name(int sfd)
{
	printf("******1.年龄****\n");
	printf("******2.性别********\n");
	printf("******3.手机号*****\n");
	printf("******4.密码*****\n");
	printf("******5.家庭住址*****\n");
	printf("******6.职位*****\n");
	printf("******7.入职年月*****\n");
	printf("请输入要修改的字段>>");
	scanf("%c", &choose);
	while(getchar()!=10);
	switch (choose)
	{
	case '1':
		msg->msgtype='1';
		printf("输入年龄>>");
		scanf("%d", &msg->info.age);
		while(getchar()!=10);
		send_recv(sfd,msg);
		break;
	case '2':
		msg->msgtype='2';
		printf("输入性别>>");
		scanf("%s", msg->info.sex);
		while(getchar()!=10);
		send_recv(sfd,msg);
		break;
	case '3':
		msg->msgtype='3';
		printf("输入手机号>>");
		scanf("%s", msg->info.tel);
		while(getchar()!=10);
		send_recv(sfd,msg);
		break;
	case '4':
		msg->msgtype='4';
		printf("输入密码>>");
		scanf("%s", msg->info.passwd);
		while(getchar()!=10);
		send_recv(sfd,msg);
		break;
	case '5':
		msg->msgtype='5';
		printf("输入家庭住址>>");
		scanf("%s", msg->info.addr);
		while(getchar()!=10);
		send_recv(sfd,msg);		
		break;
	case '6':
		msg->msgtype='6';
		printf("输入职位>>");
		scanf("%s", msg->info.work);
		while(getchar()!=10);
		send_recv(sfd,msg);
		break;
	case '7':
		msg->msgtype='7';
		printf("输入入职日期(格式2022.10.10)>>");
		scanf("%s", msg->info.date);
		while(getchar()!=10);
		send_recv(sfd,msg);
		break;
	}
	printf("请输入返回上一级>>>");
	while(getchar()!=10);
	return ;
}
int Add_fun(int sfd)
{
	bzero(msg,sizeof(MSG));
	printf("请输入姓名>>");
	scanf("%s",msg->info.name);
	while(getchar()!=10);

	printf("请输入年龄>>");
	scanf("%d",&msg->info.age);
	while(getchar()!=10);

	printf("请输入性别>>");
	scanf("%s",msg->info.sex);
	while(getchar()!=10);

	printf("请输入职位>>");
	scanf("%s",msg->info.work);
	while(getchar()!=10);

	printf("请输入电话>>");
	scanf("%s",msg->info.tel);
	while(getchar()!=10);

	printf("请输入家庭住址>>");
	scanf("%s",msg->info.addr);
	while(getchar()!=10);

	printf("请输入密码>>");
	scanf("%s",msg->info.passwd);
	while(getchar()!=10);

	printf("请输入入职日期>>");
	scanf("%s",msg->info.date);
	while(getchar()!=10);

	printf("请输入用户类型root(0) user(1)>>");
	scanf("%c",&msg->info.usertype);
	while(getchar()!=10);

	MSG *recv_ser;
	msg->msgtype='A';
	send_recv(sfd,msg);
	printf("%s\n",recv_ser->recvmsg);
	return 0;
}
int Delete_fun(int sfd)
{	msg->msgtype='D';
	printf("请输入要删除的员工姓名>>");
	scanf("%s",msg->info.name);
	send_recv(sfd,msg);
	printf("%s\n",msg->recvmsg);
	return 0;
}
int History(int sfd)
{
	msg->msgtype='H';
	strcpy(msg->info.name,"admin");
	send_recv(sfd,msg);
	printf("shchu\n");
	printf("%s\n",msg->recvmsg);
	return 0;
}
int Select_fun(int sfd)
{
	int quit = 0;
	while (1)
	{
		if (quit == 1)
		{
			break;
		}
		
		printf("******1.按人名查找*******\n");
		printf("******2.查找所有  *******\n");
		printf("******0.返回上一级*******\n");
		scanf("%c", &choose);	
		while(getchar()!=10);
		switch (choose)
		{
		case '0':
			quit = 1;
			break;
		case '1':
			msg->msgtype='F'; //server端通过此知道是人名查找
			printf("请输入要查找的人名>>");
			scanf("%s", msg->info.name);
			while(getchar()!=10);
			if (send(sfd, msg, sizeof(MSG), 0) < 0)
			{
				ERR("send");
				return -1;
			}
			bzero(msg, sizeof(MSG));
			res = recv(sfd, msg, sizeof(MSG), 0);
			if (res < 0)
			{
				ERR("recv");
				return -1;
			}
			else if (0 == res)
			{
				fprintf(stderr, "服务器关闭\n");
				break;
			}
			//打印查找内容
			printf("%s", msg->recvmsg);
			break;
		case '2':
			bzero(msg, sizeof(MSG));
			msg->msgtype='s';//查找所有
			if (send(sfd, msg, sizeof(MSG), 0) < 0)
			{
				ERR("send");
				return -1;
			}
			bzero(msg, sizeof(MSG));
			res = recv(sfd, msg, sizeof(MSG), 0);
			if (res < 0)
			{
				ERR("recv");
				return -1;
			}
			else if (0 == res)
			{
				fprintf(stderr, "服务器关闭\n");
				break;
			}
			//打印查找内容
			printf("%s", msg->recvmsg);
			break;
		}
	}
}
//普通用户登陆
int user_login(int sfd,MSG *msg)
{
	int res;
	char a;
	printf("输入用户名>>");
	scanf("%s", msg->info.name);
	while(getchar()!=10);
	printf("请输入密码>>");
	scanf("%s", msg->info.passwd);
	while(getchar()!=10);
	//发送给服务器
	if (send(sfd, msg, sizeof(MSG), 0) < 0)
	{
		ERR("send");
		return -1;
	}
	printf("send success\n");
	//接收前清空,判断是否登陆成功
	bzero(msg, sizeof(MSG));
	res = recv(sfd, msg, sizeof(MSG), 0);
	if (res < 0)
	{
		ERR("recv");
		return -1;
	}
	else if (0 == res)
	{
		fprintf(stderr, "服务器关闭\n");
		exit(-1);
	}
	else
	{
		if (strcmp(msg->recvmsg, "login_ok"))
		{
			//登陆失败
			printf("用户名或密码错误\n");
			exit(-1);
		}
		else
		{
			//登陆成功---跳转普通用户界面
			printf("1.查询\n");
			printf("2.修改\n");
			printf("3.历史记录\n");

			scanf("%s",&a);
			while(getchar()!=10);
		}
	}
	return 0;
}
//管理员登陆
int root_login(int sfd,MSG *msg)
{
	int res;
	printf("输入用户名>>");
	scanf("%s", msg->info.name);
	while(getchar()!=10);
	printf("请输入密码>>");
	scanf("%s", msg->info.passwd);
	while(getchar()!=10);
	//发送给服务器
	if (send(sfd, msg, sizeof(MSG), 0) < 0)
	{
		ERR("send");
		return -1;
	}
	printf("send success\n");
	//接收前清空,判断是否登陆成功
	bzero(msg, sizeof(MSG));
	res = recv(sfd, msg, sizeof(MSG), 0);
	if (res < 0)
	{
		ERR("recv");
		return -1;
	}
	else if (0 == res)
	{
		fprintf(stderr, "服务器关闭\n");
		exit(-1);
	}
	else
	{
		if (strcmp(msg->recvmsg, "login_ok"))
		{
			//登陆失败
			printf("用户名或密码错误\n");
			exit(-1);
		}
		else
		{
			//登陆成功---跳转管理员菜单
			root_menu(sfd);
		}
	}
	return 0;
}
void send_recv(int sfd, MSG *msg)
{
	int res;
	if (send(sfd, msg, sizeof(MSG), 0) < 0)
	{
		ERR("send");
		exit;
	}
	printf("send success\n");
	bzero(msg, sizeof(MSG));
	res = recv(sfd, msg, sizeof(MSG), 0);
	if (res < 0)
	{
		ERR("recv");
		printf("接收失败\n");
		exit;
	}
	else if (0 == res)
	{
		fprintf(stderr, "服务器关闭\n");
		exit;
	}
	printf("接收成功\n");
	printf("%s\n",msg->recvmsg);
	return ;
}
//网络初始化
int init_inet()
{
	//创建流式套接字
	int sfd = socket(AF_INET, SOCK_STREAM, 0);
	if (sfd < 0)
	{
		ERR("socket");
		return -1;
	}
	int reuse = 1;
	if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
	{
		ERR("setsockopt failed");
		return -1;
	}
	//填充要连接的服务器的IP和端口
	struct sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(PORT);
	sin.sin_addr.s_addr = inet_addr(IP);
	//连接服务器
	if (connect(sfd, (struct sockaddr *)&sin, sizeof(sin)) < 0)
	{
		ERR("connect");
		return -1;
	}
	return sfd;
}

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值