项目管理系统

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

项目要求

1服务器负责管理所有员工表单(以数据库形式其他客户端可通过网络连接服务器来查询员工表单。

2需要账号密码登陆其中需要区分管理员账号还是普通用户账号。

3管理员账号可以查看、修改、添加、删除员工信息同时具有查询历史记录功能管理员要负责管理所有的普通用户。

4普通用户只能查询修改与本人有关的相关信息其他员工信息不得查看修改。

5服务器能同时相应多台客户端的请求功能。并发

项目涉及的知识点

1.TCP通信的服务器、客户端编程流程

        1.服务器:

                1创建套接字

                2绑定ip和端口号

                3监听

                4等待客户端连接

        2.客户端:

                1创建套接字

                2连接服务器

2.服务器并发

        1多线程

        2多进程

        3IO多路复用:select

3.sqlite3数据库常用语句以及编程接口

        编译数据库接口相关c文件需要链接库 -lsqlite3

项目流程图

服务器

客户端

通信结构体的构建

/*员工基本信息*/
typedef struct staff_info{
    int  no;             //员工编号
    int  usertype;      //ADMIN 0    USER 1     
    char name[NAMELEN];    //姓名
    char passwd[8];     //密码
    int  age;             // 年龄
    char phone[NAMELEN];//电话
    char addr[DATALEN]; // 地址
    char work[DATALEN]; //职位
    char date[DATALEN];    //入职年月
    int level;            // 等级
    double salary ;        // 工资
    
}staff_info_t;


/*定义双方通信的结构体信息*/
typedef struct {
    int  msgtype;     //请求的消息类型
    int  usertype;    //ADMIN 0    USER 1       
    char username[NAMELEN];  //姓名
    char passwd[8];             //登陆密码
    char recvmsg[DATALEN];   //通信的消息
    int  flags;      //标志位
    void *released;
 staff_info_t info;      //员工信息
}MSG;

代码

头文件

 
#ifndef _COMMON_H_
#define _COMMON_H_
 
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sqlite3.h>
#include <sys/wait.h>
#include <signal.h>
#include <time.h>
#include <pthread.h>
#include <sys/stat.h>
#include <sqlite3.h>
#include <netinet/in.h>
#include <sys/select.h>
#include <pthread.h>
 
#define STAFF_DATABASE 	 "staff_manage_system.db"
 
#define USER_LOGIN 		0x00000000  // login	登陆    0x00000001
#define USER_MODIFY 	0x00000001  // user-modification  修改
#define USER_QUERY 		0x00000002  // user-query   查询
 
#define ADMIN_LOGIN 	0x10000000  // login	         登陆    0x00000001
#define ADMIN_MODIFY 	0x10000001 // admin_modification 修改
#define ADMIN_ADDUSER 	0x10000002 // admin_adduser      添加
#define ADMIN_DELUSER 	0x10000004 // admin_deluser      删除
#define ADMIN_QUERY 	0x10000008  //hitory_query       查找
#define ADMIN_HISTORY 	0x10000010  //hitory_history     历史
 
#define ADMIN_LIST      0x10000011 //列表
 
#define QUIT 			0x11111111
 
#define ADMIN 0	//管理员
#define USER  1	//用户
 
#define PASSLEN 8
#define NAMELEN 16
#define DATALEN 128
 
/*员工基本信息*/
typedef struct staff_info
{
	int  no; 					//员工编号
	int  usertype;  			//ADMIN 1	USER 2	 
	char name[NAMELEN];			//姓名
	char passwd[PASSLEN]; 		//密码
	int  age; 					// 年龄
	char phone[NAMELEN];		//电话
	char addr[DATALEN]; 		// 地址
	char work[DATALEN]; 		//职位
	char date[DATALEN];			//入职年月
	int level;					// 等级
	int salary;					// 工资
	
}staff_info_t;
 
/*定义双方通信的结构体信息*/
typedef struct 
{
	int  msgtype;       	 //请求的消息类型
	int  usertype;   		 //ADMIN 1	USER 2	   
	char username[NAMELEN];  //姓名
	char passwd[PASSLEN];	 //登陆密码
	char recvmsg[DATALEN];   //通信的消息
	int  flags;      		 //标志位
	staff_info_t info;       //员工信息
}MSG;
 
#define S_IP "10.0.12.9"
#define IP "192.168.250.100"
#define PORT "8888"
 
char user_name[NAMELEN];	 //姓名
char user_passwd[PASSLEN];	 //登陆密码
 
char history[DATALEN+100];
 
 
 
 
#endif
 

服务端

...

客户端

 
#include "common.h"

int do_login(int socketfd);
 
/**************************************
 *函数名:do_query
 *参   数:消息结构体
 *功   能:管理员查询
 ****************************************/
void do_admin_query(int sockfd, MSG *msg)
{
	system("clear");
	memset(msg, 0, sizeof(MSG));
	msg->msgtype = ADMIN_QUERY;
	char name[NAMELEN] = "";
	printf("Please enter find no:");
	scanf("%s", name);
	while (getchar() != '\n')
		;
	strcpy(msg->recvmsg, name);
	//发送查询请求
	if (send(sockfd, msg, sizeof(MSG), 0) < 0)
	{
		printf("Sending the account to the server error\n");
		return;
	}
 
	//接受服务器响应
	while (1)
	{
		recv(sockfd, msg, sizeof(MSG), 0);
		if (!strncmp(msg->recvmsg, "end", 3))
		{
			printf("find success\n");
			return;
		}
		if (!strncmp(msg->recvmsg, "no", 2))
		{
			printf("find error\n");
			return;
		}
		printf("----------------------------------\n");
		printf("staffno :%d\nusertype:%d\nname    :%s\npasswd  :%s\nage     :%d\nphone   :%s\naddr    :%s\nwork    :%s\ndate    :%s\nlevel   :%d\nsalary  :%d\n", msg->info.no, msg->info.usertype, msg->info.name, msg->info.passwd, msg->info.age, msg->info.phone, msg->info.addr, msg->info.work, msg->info.date, msg->info.level, msg->info.salary);
		printf("----------------------------------\n");
	}
}
 
/**************************************
 *函数名:admin_modification
 *参   数:消息结构体
 *功   能:管理员修改
 ****************************************/
void do_admin_modification(int sockfd, MSG *msg) //管理员修改
{
	system("clear");
	memset(msg, 0, sizeof(MSG));
	msg->msgtype = ADMIN_MODIFY;
	int opt = 0;
	int tem;
	char str1[NAMELEN] = "";
	char str2[DATALEN] = "";
	char str3[PASSLEN] = "";
	printf("please enter user name:");
	scanf("%s",msg->username);
	printf("1:no\n2:usertype\n3:name\n4:passwd\n5:age\n6:phone\n7:addr\n8:work\n9:date\n10:level\n11:salary\nplease enter change option:");
	scanf("%d", &opt);
	while(getchar()!='\n');
	
	switch (opt)
	{
	case 1:
		msg->flags = 1;
		printf("please enter no:");
		scanf("%d", &tem);
		msg->info.no = tem;
		break;
	case 2:
		msg->flags = 2;
		printf("please enter usertype:");
		scanf("%d", &tem);
		msg->info.usertype = tem;
		break;
	case 3:
		msg->flags = 3;
		printf("please enter name:");
		fgets(str1,NAMELEN,stdin);
		str1[strlen(str1)-1]='\0';
		strcpy(msg->info.name, str1);
		break;
	case 4:
		msg->flags = 4;
		printf("please enter passwd:");
		fgets(str3,PASSLEN,stdin);
		str3[strlen(str3)-1]='\0';
		strcpy(msg->info.passwd, str1);
		break;
	case 5:
		msg->flags = 5;
		printf("please enter age:");
		scanf("%d", &tem);
		msg->info.age = tem;
		break;
	case 6:
		msg->flags = 6;
		printf("please enter phone:");
		fgets(str1,NAMELEN,stdin);
		str1[strlen(str1)-1]='\0';
		strcpy(msg->info.phone, str1);
		break;
	case 7:
		msg->flags = 7;
		printf("please enter addr:");
		fgets(str2,DATALEN,stdin);
		str2[strlen(str2)-1]='\0';
		strcpy(msg->info.addr, str2);
		break;
	case 8:
		msg->flags = 8;
		printf("please enter work:");
		fgets(str2,DATALEN,stdin);
		str2[strlen(str2)-1]='\0';
		strcpy(msg->info.work, str2);
		break;
	case 9:
		msg->flags = 9;
		printf("please enter date:");
		fgets(str2,DATALEN,stdin);
		str2[strlen(str2)-1]='\0';
		strcpy(msg->info.date, str2);
		break;
	case 10:
		msg->flags = 10;
		printf("please enter level:");
		scanf("%d", &tem);
		msg->info.level = tem;
		break;
	case 11:
		msg->flags = 11;
		printf("please enter salary:");
		scanf("%d", &tem);
		msg->info.salary = tem;
		break;
	default:
		printf("enter error\n");
		return;
	}
	if (send(sockfd, msg, sizeof(MSG), 0) < 0)
	{
		printf("Sending the account to the server error\n");
		return;
	}
	
 
	system("clear");
 
	recv(sockfd, msg, sizeof(MSG), 0);
	if (!strncmp(msg->recvmsg, "ok", 2))
	{
		printf("user change success\n");
		return;
	}
	else if(!strncmp(msg->recvmsg, "no", 2))
	{
		printf("user change error\n");
		return;
	}
	
}
 
/**************************************
 *函数名:admin_adduser
 *参   数:消息结构体
 *功   能:管理员创建用户
 ****************************************/
void do_admin_adduser(int sockfd, MSG *msg) //管理员添加用户
{
	system("clear");
	int tem;
	char str1[NAMELEN] = "";
	char str2[DATALEN] = "";
	char str3[PASSLEN] = "";
 
	memset(msg, 0, sizeof(MSG));
	msg->msgtype = ADMIN_ADDUSER;
	printf("please enter no:");
	scanf("%d", &tem);
	msg->info.no = tem;
 
	printf("please enter usertype:");
	scanf("%d", &tem);
	msg->info.usertype = tem;
	while (getchar() != '\n');
 
	printf("please enter name:");
	fgets(str1,NAMELEN,stdin);
	str1[strlen(str1)-1]='\0';
	strcpy(msg->info.name, str1);
 
	printf("please enter passwd:");
	fgets(str3,PASSLEN,stdin);
	str3[strlen(str3)-1]='\0';
	strcpy(msg->info.passwd, str3);
 
	printf("please enter age:");
	scanf("%d", &tem);
	msg->info.age = tem;
	while (getchar() != '\n');
 
	printf("please enter phone:");
	fgets(str1,NAMELEN,stdin);
	str1[strlen(str1)-1]='\0';
	strcpy(msg->info.phone, str1);
 
	printf("please enter addr:");
	fgets(str2,DATALEN,stdin);
	str2[strlen(str2)-1]='\0';
	strcpy(msg->info.addr, str2);
 
	printf("please enter work:");
	fgets(str2,DATALEN,stdin);
	str2[strlen(str2)-1]='\0';
	strcpy(msg->info.work, str2);
 
	printf("please enter date:");
	fgets(str2,DATALEN,stdin);
	str2[strlen(str2)-1]='\0';
	strcpy(msg->info.date, str2);
 
	printf("please enter level:");
	scanf("%d", &tem);
	msg->info.level = tem;
 
	printf("please enter salary:");
	scanf("%d", &tem);
	msg->info.salary = tem;
 
	if (send(sockfd, msg, sizeof(MSG), 0) < 0)
	{
		printf("Sending the account to the server error\n");
		return;
	}
 
	recv(sockfd, msg, sizeof(MSG), 0);
	if (!strncmp(msg->recvmsg, "ok", 2))
	{
		printf("user add success\n");
		return;
	}
	else if (!strncmp(msg->recvmsg, "no", 2))
	{
		printf("user add error\n");
		return;
	}
	
 
	printf("user add error\n");
}
 
/**************************************
 *函数名:admin_deluser
 *参   数:消息结构体
 *功   能:管理员删除用户
 ****************************************/
void do_admin_deluser(int sockfd, MSG *msg) //管理员删除用户
{
	system("clear");
	msg->msgtype = ADMIN_DELUSER;
	int no = 0;
	printf("pelase enter delete user NO:");
	scanf("%d", &no);
	msg->info.no = no;
	if (send(sockfd, msg, sizeof(MSG), 0) < 0)
	{
		printf("Sending the account to the server error\n");
		return;
	}
	recv(sockfd, msg, sizeof(MSG), 0);
	if (!strncmp(msg->recvmsg, "ok", 2))
	{
		printf("user delete success\n");
		return;
	}
	else if (!strncmp(msg->recvmsg, "no", 2))
	{
		printf("user delete error\n");
		return;
	}
}
 
/**************************************
 *函数名:do_history
 *参   数:消息结构体
 *功   能:管理员查看历史记录
 ****************************************/
void do_admin_history(int sockfd, MSG *msg)
{
	system("clear");
	memset(msg, 0, sizeof(MSG));
	msg->msgtype = ADMIN_HISTORY;
	putchar(10);
 
	printf("   %s     |     %s     |                        %s                        \n","data","time","log");
 
 
 
	if (send(sockfd, msg, sizeof(MSG), 0) < 0)
	{
		printf("Sending the account to the server error\n");
		return;
	}
	
	
 
	while (1)
	{
		recv(sockfd, msg, sizeof(MSG), 0);
		if (msg->flags == 1)
		{
			printf("find success\n");
			break;
		}
		if (msg->flags == 2)
		{
			printf("find error\n");
			break;
		}
 
		printf("%s",msg->recvmsg);
 
		send(sockfd, msg, sizeof(MSG), 0);
 
	}
 
}
 
void do_admin_list(int sockfd, MSG *msg)
{
	system("clear");
	memset(msg, 0, sizeof(MSG));
	msg->msgtype = ADMIN_LIST;
	char name[NAMELEN] = "";
	//发送查询请求
	if (send(sockfd, msg, sizeof(MSG), 0) < 0)
	{
		printf("Sending the account to the server error\n");
		return;
	}
 
	//接受服务器响应
	while (1)
	{
		recv(sockfd, msg, sizeof(MSG), 0);
		if (!strncmp(msg->recvmsg, "endd", 4))
		{
			printf("find success\n");
			return;
		}
		if (!strncmp(msg->recvmsg, "no", 2))
		{
			printf("find error\n");
			return;
		}
		//printf("%d\t%d\t%s\t%s\t%d\t%s\t%s\t%s\t%s\t%d\t%d\n", msg->info.no, msg->info.usertype, msg->info.name, msg->info.passwd, msg->info.age, msg->info.phone, msg->info.addr, msg->info.work, msg->info.date, msg->info.level, msg->info.salary);
		printf("----------------------------------\n");
		printf("staffno :%d\nusertype:%d\nname    :%s\npasswd  :%s\nage     :%d\nphone   :%s\naddr    :%s\nwork    :%s\ndate    :%s\nlevel   :%d\nsalary  :%d\n", msg->info.no, msg->info.usertype, msg->info.name, msg->info.passwd, msg->info.age, msg->info.phone, msg->info.addr, msg->info.work, msg->info.date, msg->info.level, msg->info.salary);
		printf("----------------------------------\n");
 
		send(sockfd, msg, sizeof(MSG), 0);
	}
}
 
/**************************************
 *函数名:admin_menu
 *参   数:套接字、消息结构体
 *功   能:管理员菜单
 ****************************************/
void admin_menu(int sockfd, MSG *msg)
{
	int op = -1;
	printf(" ************ 1  查看   ************\n");
	printf(" ************ 2  修改   ************\n");
	printf(" ************ 3  添加   ************\n");
	printf(" ************ 4  删除   ************\n");
	printf(" ************ 5  列表   ************\n");
	printf(" ************ 6  清屏   ************\n");
	printf(" ************ 7 历史记录 ************\n");
	printf(" ************ 0 退回上级 ************\n");
	printf("请输入选项:");
	scanf("%d", &op);
	while(getchar()!='\n');
	if(op < 0 || op > 7)
	{
		system("clear");
		printf("输入错误 请重新输入\n");
		admin_menu(sockfd,msg);
	}
	switch (op)
	{
	case 0:
		system("clear");
		do_login(sockfd);
		break;
	case 1:
		do_admin_query(sockfd, msg);
		break;
	case 2:
		do_admin_modification(sockfd, msg);
		break;
	case 3:
		do_admin_adduser(sockfd, msg);
		break;
	case 4:
		do_admin_deluser(sockfd, msg);
		break;
	case 5:
		do_admin_list(sockfd, msg);
		break;
	case 6:
		system("clear");
		break;
	case 7:
		do_admin_history(sockfd,msg);
		break;
	default:
		printf("enter error\n");
		return;
	}
}
 
/**************************************
 *函数名:do_query
 *参   数:消息结构体
 *功   能:用户查找
 ****************************************/
void do_user_query(int sockfd, MSG *msg)
{
	system("clear");
	memset(msg, 0, sizeof(MSG));
	msg->msgtype = USER_QUERY;
	strcpy(msg->username, user_name);
	strcpy(msg->passwd,user_passwd);
	//发送查询请求
	if (send(sockfd, msg, sizeof(MSG), 0) < 0)
	{
		printf("Sending the account to the server error\n");
		return;
	}
 
	//接受服务器响应
	while(1)
	{
	recv(sockfd, msg, sizeof(MSG), 0);
	if (!strncmp(msg->recvmsg, "end", 3))
	{
		printf("find success\n");
		return;
	}
	if (!strncmp(msg->recvmsg, "no", 2))
	{
		printf("find error\n");
		return;
	}
	printf("----------------------------------\n");
	printf("staffno :%d\nusertype:%d\nname    :%s\npasswd  :%s\nage     :%d\nphone   :%s\naddr    :%s\nwork    :%s\ndate    :%s\nlevel   :%d\nsalary  :%d\n", msg->info.no, msg->info.usertype, msg->info.name, msg->info.passwd, msg->info.age, msg->info.phone, msg->info.addr, msg->info.work, msg->info.date, msg->info.level, msg->info.salary);
	printf("----------------------------------\n");
	}
}
 
/**************************************
 *函数名:do_modification
 *参   数:消息结构体
 *功   能:用户修改
 ****************************************/
void do_user_modification(int sockfd, MSG *msg)
{
	
	system("clear");
	memset(msg, 0, sizeof(MSG));
	msg->msgtype = USER_MODIFY;
	strcpy(msg->username, user_name);
	strcpy(msg->passwd,user_passwd);
 
	int opt = 0;
	int tem;
	char str1[NAMELEN] = "";
	char str2[DATALEN] = "";
	char str3[PASSLEN] = "";
	printf("1:no\n2:usertype(Please contact the administrator)\n3:name\n4:passwd\n5:age\n6:phone\n7:addr\n8:work\n9:date\n10:level\n11:salary\nplease enter change option:");
	scanf("%d", &opt);
	while(getchar()!='\n');
	
	switch (opt)
	{
	case 1:
		msg->flags = 1;
		printf("please enter no:");
		scanf("%d", &tem);
		msg->info.no = tem;
		break;
	case 2:
		msg->flags = 2;
		printf("please enter usertype:");
		scanf("%d", &tem);
		msg->info.usertype = tem;
		break;
	case 3:
		msg->flags = 3;
		printf("please enter name:");
		fgets(str1,NAMELEN,stdin);
		str1[strlen(str1)-1]='\0';
		strcpy(msg->info.name, str1);
		break;
	case 4:
		msg->flags = 4;
		printf("please enter passwd:");
		fgets(str3,PASSLEN,stdin);
		str3[strlen(str3)-1]='\0';
		strcpy(msg->info.passwd, str3);
		break;
	case 5:
		msg->flags = 5;
		printf("please enter age:");
		scanf("%d", &tem);
		msg->info.age = tem;
		break;
	case 6:
		msg->flags = 6;
		printf("please enter phone:");
		fgets(str1,NAMELEN,stdin);
		str1[strlen(str1)-1]='\0';
		strcpy(msg->info.phone, str1);
		break;
	case 7:
		msg->flags = 7;
		printf("please enter addr:");
		fgets(str2,DATALEN,stdin);
		str2[strlen(str2)-1]='\0';
		strcpy(msg->info.addr, str2);
		break;
	case 8:
		msg->flags = 8;
		printf("please enter work:");
		fgets(str2,DATALEN,stdin);
		str2[strlen(str2)-1]='\0';
		strcpy(msg->info.work, str2);
		break;
	case 9:
		msg->flags = 9;
		printf("please enter date:");
		fgets(str2,DATALEN,stdin);
		str2[strlen(str2)-1]='\0';
		strcpy(msg->info.date, str2);
		break;
	case 10:
		msg->flags = 10;
		printf("please enter level:");
		scanf("%d", &tem);
		msg->info.level = tem;
		break;
	case 11:
		msg->flags = 11;
		printf("please enter salary:");
		scanf("%d", &tem);
		msg->info.salary = tem;
		break;
	default:
		printf("enter error\n");
		return;
	}
 
	if (send(sockfd, msg, sizeof(MSG), 0) < 0)
	{
		printf("Sending the account to the server error\n");
		return;
	}
	
 
	system("clear");
 
	recv(sockfd, msg, sizeof(MSG), 0);
	if (!strncmp(msg->recvmsg, "ok", 2))
	{
		printf("user change success\n");
		return;
	}
	else if(!strncmp(msg->recvmsg, "no", 2))
	{
		printf("user change error\n");
		return;
	}
}
 
/**************************************
 *函数名:user_menu
 *参   数:消息结构体
 *功   能:用户菜单
 ****************************************/
void user_menu(int sockfd, MSG *msg)
{
	int op = -1;
	printf(" ************ 1  查看  ************\n");
	printf(" ************ 2  修改  ************\n");
	printf(" ************ 3  清屏  ************\n");
	printf(" ************ 0  退回上级  *********\n");
	printf("请输入选项:");
	scanf("%d", &op);
	while(getchar()!='\n');
	if(op < 0 || op > 3)
	{
		system("clear");
		printf("输入错误 请重新输入\n");
		user_menu(sockfd,msg);
	}
	switch (op)
	{
	case 0:
		system("clear");
		do_login(sockfd);
		break;
	case 1:
		do_user_query(sockfd, msg);
		break;
	case 2:
		do_user_modification(sockfd, msg);
		break;
	case 3:
		system("clear");
		break;
	default:
		printf("enter error\n");
		break;
	}
}
 
int admin_or_user_login(int sockfd, MSG *msg)
{
	
	//输入用户名和密码
	memset(msg->username, 0, NAMELEN);
	printf("请输入用户名:");
	scanf("%s", msg->username);
	getchar();
 
	memset(msg->passwd, 0, DATALEN);
	printf("请输入密码: ");
	scanf("%s", msg->passwd);
	getchar();
 
	strcpy(user_name,msg->username);
	strcpy(user_passwd,msg->passwd);
 
	//发送登陆请求
	if (send(sockfd, msg, sizeof(MSG), 0) < 0)
	{
		printf("Sending the account to the server error\n");
		return -1;
	}
 
	//接受服务器响应
	recv(sockfd, msg, sizeof(MSG), 0);
 
	//判断是否登陆成功
	if (strncmp(msg->recvmsg, "OK", 2) == 0)
	{
		if (msg->usertype == ADMIN)
		{
			system("clear");
			printf("亲爱的管理员欢迎您登陆员工管理系统\n");
			while (1)
			{
				admin_menu(sockfd, msg);
			}
		}
		else if (msg->usertype == USER)
		{
			system("clear");
			printf("亲爱的用户欢迎您登陆员工管理系统\n");
			while (1)
			{
				user_menu(sockfd, msg);
			}
		}
	}
	else
	{
		printf("登陆失败%s\n", msg->recvmsg);
		admin_or_user_login(sockfd,msg);
	}
 
	return 0;
}
 
/************************************************
 *函数名:do_login
 *参   数:套接字、消息结构体
 *返回值:是否登陆成功
 *功   能:登陆
 *************************************************/
int do_login(int socketfd)
{
	int n;
	MSG msg;
 
	while (1)
	{
		printf("**********************************\n");
		printf("********  1: 管理员模式   ********\n");
		printf("********  2:普通用户模式  ********\n");
		printf("********  0: 断开客户端    ********\n");
		printf("**********************************\n");
		printf("请输入您的选择(数字>> ");
		scanf("%d", &n);
		while(getchar()!='\n');
		if(n < 0 || n > 2)
		{
			system("clear");
			printf("输入错误 请重新输入\n");
			do_login(socketfd);
		}
 
		switch (n)
		{
		case 1:
			//管理员模式登录
			msg.msgtype = ADMIN_LOGIN; // 1
			msg.usertype = ADMIN;	   // 0
			break;
		case 2:
			//普通用户登录
			msg.msgtype = USER_LOGIN;
			msg.usertype = USER;
			break;
		case 0:
			//退出
			msg.msgtype = QUIT;
			if (send(socketfd, &msg, sizeof(MSG), 0) < 0)
			{
				perror("do_login send");
				return -1;
			}
			close(socketfd);
			exit(0);
		default:
			printf("您的输入有误请重新输入\n");
		}
 
		admin_or_user_login(socketfd, &msg);
	}
}
 
int main(int argc, const char *argv[])
{
	// socket->填充->绑定->监听->等待连接->数据交互->关闭
	system("clear");
	int socketfd;
	//创建网络通信的套接字 流式套接字
	if (-1 == (socketfd = socket(AF_INET, SOCK_STREAM, 0)))
	{
		printf("socket error\n");
		return -1;
	}
	printf("socket success\n");
 
	//填充网络结构体
	//填充服务器网路信息结构体
	struct sockaddr_in sin;
	//填充为IPV4地址
	sin.sin_family = AF_INET;
	//填充服务器IP
	sin.sin_addr.s_addr = inet_addr(IP);
	//填充服务器端口号
	sin.sin_port = htons(atoi(PORT));
 
	//连接服务器
	if (-1 == connect(socketfd, (struct sockaddr *)&sin, sizeof(sin)))
	{
		printf("connect error\n");
		return -1;
	}
	printf("connect suceess\n");
 
	//登陆
	do_login(socketfd);
 
	//关闭套接字
	close(socketfd);
 
	return 0;
}

测试现象

Ubuntu 18.04 PZB - VMware

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6