C/S模型-多进程-简易版学生-管理系统(带数据库)

时间:2021-07-11 07:46:53

简介:

【1】数据:

  学生信息:姓名name + 账号account + 分数score

  登录信息:账号account + 密码password(学生、管理员)

【2】C/S模型,使用fork实现多进程交互

【3】Client:

  1)登录:学生登录,管理员登陆

  2)管理员:修改密码、添加学生信息、删除学生信息、查找学生信息(指定account、所有)、修改学生成绩

  3)学生:修改密码、查看本人信息、查看指定account学生信息、查看所有学生信息

【4】Server:

  1)登录验证

  2)密码修改

  3)增/删学生信息

  4)查找

  5)修改

 

实现:

【1】环境:

  数据库使用:MySQL

  系统:Ubuntu 16.04  g++ (最新版)

  编译命令:g++ name.cpp -o a -std=c++11 `mysql_config --cflags --libs`

【2】数据库:三个表

  student :学生成绩(id,name,account,score)

  login_student :学生登录(id,account,password)

  login_manager :管理员(id,account,password)

  ###数据准本的txt,写了个程序(cpp)将txt读到了数据库里,由于个人练习,仅使用了1个管理员+3个学生

【3】功能请求编码:在c/s传输中,使用char[]进行接收发送,并且本次练习中,功能较少,使用char[0]进行功能编号

  ‘0’‘1’:登录

  'a'-'f':管理员请求

  ‘A'-'D':学生请求

//客户端发送格式
 
管理员登录:0account password
学生登录:1account password
 
管理员功能:
修改密码:aaccount newpwd
增加学生信息:bname account pwd score
删除:caccount
查找指定account:daccount
查找所有:e
修改分数:faccount newscore

学生功能:
修改密码:Aaccount pwd
查看自己:Baccount
查看他人:Caccount
查看所有:D

//服务端发送格式
//非查找
“1” 成功
“0” 失败
//查找
返回结果集

【4】流程

客户端:

  登录选择:0 1

  输入账号密码

  登录验证:send recv,收到“1”登录成功,否则失败

  功能显示:0显示管理员功能  1显示学生功能  q退出

  输入:a-f 或 A-D

  执行对应功能,有输入的输入对应数据,send  recv

  结果验证:执行成功或者有数据返回,成功输出成功,有数据就输出数据

  转到功能显示

 

服务器端:

  数据库初始化,套接字初始化

  收到连接请求,fork子进程处理连接,主进程继续accept

  子进程:对recv收到的数据进行处理,构建sql查询语句,调用mysql api执行,对返回结果验证,send

 

代码:

#数据,0是id,自动增长
0 guanliyuan 123456

0 hzk 111111

0 abc 222222

0 xyz 333333

0 hzk hzk 240

0 abc abc 220

0 xyz xyz 230

  

//从txt读取数据至数据库中
#include <iostream>
#include <mysql/mysql.h>

#include <string>
#include <cstring>
#include <fstream>
using namespace std;

//read the data from "data.txt"
//write the data to database

int main(int argc,char** argv){
	MYSQL conn;
	mysql_init(&conn);

	if(mysql_real_connect(&conn,"localhost","root","961225","Sample",
		0,NULL,CLIENT_FOUND_ROWS)){
		cout<<"connect sc \n";
	}
	else{
		cout<<"fail \n";
		mysql_close(&conn);
		return 0;
	}

	
	ifstream in("data.txt");
	//default : one manager,three students,
	int a=1,b=3,c=3;
	if(argc==4){
		a=atoi(argv[1]);
		b=atoi(argv[2]);
		c=atoi(argv[3]);
	}
	int i,res;
	int c1,c4;
	string c2,c3;
	for(i=0;i<a;++i){
		in>>c1>>c2>>c3;
		string tmp("insert into login_teacher values(");
		tmp+="0,'"+c2+"','"+c3+"')";
		res=mysql_query(&conn,tmp.c_str());
		if(res) cout<<"error \n";
		else cout<<"ok \n";
	}	

	for(i=0;i<b;++i){
		in>>c1>>c2>>c3;
		string tmp("insert into login_student values(");
		tmp+="0,'"+c2+"','"+c3+"')";
		res=mysql_query(&conn,tmp.c_str());
		if(res) cout<<"error \n";
		else cout<<"ok \n";
	}	

	for(i=0;i<c;++i){
		in>>c1>>c2>>c3>>c4;
		string tmp("insert into student values(");
		tmp+="0,'"+c2+"','"+c3+"',"+to_string(c4)+")";
		res=mysql_query(&conn,tmp.c_str());
		if(res) cout<<"error \n";
		else cout<<"ok \n";
	}	

	in.close();	

	mysql_close(&conn);
	return 0;
}

  

//客户端
#include <iostream>
#include <string>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <cstdlib>
#include <cstring>

using std::cout;
using std::cin;
using std::string;
using std::to_string;
using std::endl;
const unsigned int port=8888;

void menu(int cho){
	if(cho==0){//teacher
		cout<<"----------Teacher------------\n";
		cout<<"a.Change password \n";
		cout<<"b.Add student information \n";
		cout<<"c.Del student information with account \n";
		cout<<"d.Find someone with account \n";
		cout<<"e.Find all \n";
		cout<<"f.Modify someone with account and score \n";
	}
	else{
		cout<<"----------Student------------\n";
		cout<<"A.Change password \n";
		cout<<"B.Find self \n";
		cout<<"C.Find someone with account \n";
		cout<<"D.Find all \n";
		cout<<"E.score is error with right score \n";
	}
	cout<<"q.exit \n";
	cout<<"-----------------------------\n";
	cout<<"Input:";
}

void recv_send(int s,string acc,int cho){
	string name,account,pwd;
	int score;
	while(1){	
		menu(cho);
		char buf[100]={0};
		//cin send recv display
		cin>>buf[0];
		if(buf[0]=='q') break;
		if(cho==0){
			switch(buf[0]){
				case 'a':	cout<<"New password:";	
							cin>>pwd;
							pwd=acc+' '+pwd;
							strcat(buf,pwd.c_str());	
							break;
				case 'b':	cout<<"New student info:name,account,password,score \n";
							cin>>name>>account>>pwd>>score;
							name+=' '+account+' '+pwd+' '+to_string(score);
							strcat(buf,name.c_str());
							break;
				case 'c':	cout<<"Deleted account:";
							cin>>account;	
							strcat(buf,account.c_str());
							break; 
				case 'd':	cout<<"Found account:";
							cin>>account;					
							strcat(buf,account.c_str());
							break;
				case 'e':	break;
				case 'f':	cout<<"Modified score:account,score \n";
							cin>>account>>score;
							account+=' '+to_string(score);
							strcat(buf,account.c_str());
							break;
				default:	cout<<"error input,continue. \n";continue;
			}
		}
		else{
			switch(buf[0]){
				case 'A':	cout<<"New password:";	
							cin>>pwd;
							pwd=acc+' '+pwd;
							strcat(buf,pwd.c_str());	
							break;
				case 'B':	strcat(buf,acc.c_str());
							break;
				case 'C':	cout<<"Found account:";
							cin>>account;						
							strcat(buf,account.c_str());
							break; 
				case 'D':	break; 
				//case 'E':	cout<<"Error information!right score is:";
				//			cin>>score;
				//			account=acc+' '+to_string(score);
				//			strcat(buf,account.c_str());
				//			break;
				default:	cout<<"error input,continue. \n";continue;
			}

		}
		send(s,buf,strlen(buf)+1,0);
		
		char buff[1024]={0};
		recv(s,buff,1024,0);
		switch(buf[0]){
			case 'a':case 'b':case 'c':case 'f':case 'A':case 'E':
				if( buff[0]=='1' ) cout<<"Completed \n";
				else cout<<"Failed \n";
				break;

			case 'd':case 'e':case 'B':case 'C':case 'D':
				for(int i=0;i<strlen(buff);++i) cout<<buff[i];
				cout<<endl;
				break;
		}
	}
}
void deal(int s,const struct sockaddr_in& addr){
	int err=connect(s,(struct sockaddr*)&addr,sizeof(addr));
	//safe

	//login
	int cho;	
	cout<<"Choose your card:teacher 0,student 1 \nInput:";	
	cin>>cho;
	
	string account,password;
	int ret;
	while(1){	
		cout<<"\nAccount:";	cin>>account;
		cout<<"Password:"; 	cin>>password;
	
		string buf("");
		buf+=cho+'0';
		buf+=account+' '+password;
		send(s,buf.c_str(),buf.length()+1,0);
		
		char buff[100]={0};
		recv(s,buff,100,0);
		if( strcmp(buff,"1") ==0){
			cout<<"Login sc \n";
			ret=1;
			break;
		}
		else{
			cout<<"Login fail \ncontinue login?('y' or 'n')\nInput";
			char c;
			cin>>c;
			if(c!='y'){
				ret=3;
				break;
			}		 
		}
	}

	if(ret==1)
		recv_send(s,account,cho);
	else cout<<"exit\n";
}

int main(int argc,char** argv){
	int s=socket(AF_INET,SOCK_STREAM,0);
	//safe
	sockaddr_in addr;
	bzero(&addr,sizeof(addr));
	addr.sin_family=AF_INET;
	addr.sin_port=htons(port);
	addr.sin_addr.s_addr=htonl(INADDR_ANY);
	
	deal(s,addr);
	
	close(s);

	return 0;
}

  

//服务器端
#include <iostream>
#include <string>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <mysql/mysql.h>

using std::vector;
using std::cout;
using std::cin;
using std::string;
using std::to_string;
using std::endl;
const unsigned int port=8888;
const unsigned int backlog=100;

MYSQL conn;

int Init_mysql(){
    mysql_init(&conn);
    if(mysql_real_connect(&conn,"localhost","root","961225","Sample",
        0,NULL,CLIENT_FOUND_ROWS)){
        cout<<"connect sc \n";
    }
    else{
        cout<<"fail \n";
        mysql_close(&conn);
        return -1;
    }
    return 0;
}

int Socket(){
    int s=socket(AF_INET,SOCK_STREAM,0);
    //safe
    sockaddr_in addr;
    bzero(&addr,sizeof(addr));
    addr.sin_family=AF_INET;
    addr.sin_port=htons(port);
    addr.sin_addr.s_addr=htonl(INADDR_ANY);
    
    int res=bind(s,(struct sockaddr*)&addr,sizeof(addr));
    //safe
    res=listen(s,backlog);
    //safe
    return s;
}

vector<string> split(const char* buf){
    vector<string> res;
    int i=0;
    int len=strlen(buf);
    string tmp;
    while(i<len){
        tmp="";
        for(;i<len && buf[i]!=' ';++i) tmp+=buf[i];
        res.push_back(tmp);
        ++i;
    }
    return res;
}

void send(int c,char cho,char* buf){
    vector<string> res;
    string str="";
    char buffer[1024]={0};
    switch(cho){
        case '0':case '1':
            res=split(buf);
            str="select id from login_";
            if(cho=='0') str+="teacher ";
            else str+="student ";
            str+="where account='"+res[0]+"' and password='"+res[1]+"'";
            //exec
            mysql_query(&conn,str.c_str());
            {
            MYSQL_RES* ret=mysql_store_result(&conn);
            int rows=mysql_num_rows(ret);
            if(rows==0) strcpy(buffer,"0");
            else strcpy(buffer,"1");
            }
            break;

        case 'a':case 'A':
            res=split(buf);
            str="update login_";
            if(cho=='a') str+="teacher ";
            else str+="student ";
            str+="set password='"+res[1]+"' where account='"+res[0]+"'";
cout<<str<<endl;
            //exec
            {            
            int res=mysql_query(&conn,str.c_str());
            if(res) strcpy(buffer,"0");
            else strcpy(buffer,"1");
            }
            break;
        case 'b':
            res=split(buf);
            str="insert into login_student values(0,'"+res[1]+"','"+res[2]+"')";
cout<<str<<endl;
            //exec
            {
            int res=mysql_query(&conn,str.c_str());
            if(res){ strcpy(buffer,"0");break;}
            }            
            str="insert into student values(0,'"+res[0]+"','"+res[1]+"','"+res[3]+"')";
cout<<str<<endl;
            {
            int res=mysql_query(&conn,str.c_str());
            if(res) strcpy(buffer,"0");
            else strcpy(buffer,"1");
            }
            break;

        case 'c':
            res=split(buf);
            str="delete from login_student where account='"+res[0]+"'";
cout<<str<<endl;
            //exec
            {            
            int res=mysql_query(&conn,str.c_str());
            if(res){ strcpy(buffer,"0");break;}
            }

            str="delete from student where account='"+res[0]+"'";
cout<<str<<endl;
            //exec
            {            
            int res=mysql_query(&conn,str.c_str());
            if(res) strcpy(buffer,"0");
            else strcpy(buffer,"1");
            }
            break;
        case 'd':case 'B':case 'C':case 'e':case 'D':
            if(cho=='e' || cho=='D') str="select * from student";
            else{
                res=split(buf);
                str="select * from student where account='"+res[0]+"'";
            }
cout<<str<<endl;
            //exec
            {            
            mysql_query(&conn,str.c_str());
            MYSQL_RES* result=NULL;
            result=mysql_store_result(&conn);            
            int cols=mysql_num_fields(result);

            MYSQL_ROW row=NULL;
            row=mysql_fetch_row(result);
            strcpy(buffer,"id\tname\taccount\tscore\n");    
            while(row){
                for(int i=0;i<cols;++i){
                    strcat(buffer,row[i]);
                    strcat(buffer,"\t");
                }
                strcat(buffer,"\n");
                row=mysql_fetch_row(result);
            }
            mysql_free_result(result);
            }
            break;

        case 'f':
            res=split(buf);
            str="update student set score='"+res[1]+"' where account='"+res[0]+"'";
cout<<str<<endl;
            //exec
            {            
            int res=mysql_query(&conn,str.c_str());
            if(res) strcpy(buffer,"0");
            else strcpy(buffer,"1");
            }
            break;
        
        
        
        //case 'E':
    }
    send(c,buffer,strlen(buffer)+1,0);
}

void recv_send(int c){
    while(1){
        char buf[100]={0};
        recv(c,buf,100,0);
        send(c,buf[0],&buf[1]);
    }
}
void deal(int s){
    while(1){
        sockaddr_in addr;
        socklen_t len;
        int c=accept(s,(struct sockaddr*)&addr,&len);
        //safe
        pid_t p=fork();
        //safe
        if(p==0){
            close(s);
            recv_send(c);
        }
        else if(p>0){
            close(c);
        }

    }
}

int main(int argc,char** argv){
    if( Init_mysql()==-1) return -1;

    int s=Socket();
        
    deal(s);
    
    close(s);

    mysql_close(&conn);

    return 0;
}