LINUX考试控制系统的设计与实现

本文介绍了一种基于定时器和进程间通信的考试管理系统,考生通过SSH远程登录,系统会根据登录情况复制试卷、检查IP一致性、显示考试注意事项,并在规定时间内控制考试流程。提交试卷后禁止重复登录,程序设计巧妙地结合字典树和守护进程实现后台运行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

功能需求:
利用定时器、进程间信号通信等知识,实现对整个考试过程的控制。考生通过ssh远程登录到考试服务器,
(1)若首次登录则从特定目录复制试卷到用户主目录并命名为用户的登录名,然后记录考生的登录信息并显示考试注意事项,登录信息包括:用户名、登录IP、时间、考试是否已经结束。设置定时器:15分钟提示、5分钟提示(通过write)、时间用完后结束考试(结束用户登录);
(2)若非首次登录,首先检查是否和首次登录的IP是否一致。若不一致关闭登录;若一致再检查考试是否结束,若已经结束,关闭登录,若考试尚未结束重新设置定时器。
(3)要求为考生显示出考试的注意事项,例如考生通过输入 notice 命令即可显示考试的注意事项。该系统还应该具有 submit 功能,即提交试卷,且试卷提交之后就不允许在同一 IP 再登录了。
由于实习时间限制,该程序号存在一个重要问题,即不能置于后台运行。

主体思路还是用字典树维护用户信息,hash绑定用户名和IP。利用管道完成父子进程的通信(所有信息需放在一个字符串中,否则会阻塞)。利用当地时间转换成到1970年的秒数控制时间。利用守护进程使得程序在 后台运行。将目录放在/bin/下,是考生进入系统后自动运行(这一步没有完成)。

#include <stdio.h>
#include <stdlib.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<string.h>
#include<unistd.h>
#include<time.h>
#include<fcntl.h>
#include<signal.h>
#define N 1005
#define M 20000005
#define min 60
//#define int long long
#define ll int
int pipe_fd[2];
char buf_r[N],buf_w[N];
pid_t re;
int fin;
ll f[M];
int Tire[N][30],Tot=1;
int End[M],Use[M];
int tag=60;
int flag;
int ti=24;
void Insert(char s[])
{
	int sz=strlen(s);
	int p=1,i;
	for(i=0;i<sz;i++)
	{
		int ch=s[i]-'a';
		if(!Tire[p][ch])  Tire[p][ch]=++Tot;
		p=Tire[p][ch];
	}
	End[p]=1;
}
int Serch(char s[])
{
	int sz=strlen(s);
	int p=1,i;
	for(i=0;i<sz;i++)
	{
		p=Tire[p][s[i]-'a'];
		if(!p)  return 0;
	}
	if(!End[p])  return 0;
	Use[p]++;
	if(Use[p]==1)  return 1;
	return 2;
}
int tire[N][30],tot=1;
int end[M],use[M];
void insert(char s[])
{
	int sz=strlen(s);
	int p=1,i;
	for(i=0;i<sz;i++)
	{
		int ch=s[i]-'a';
		if(!tire[p][ch])  tire[p][ch]=++tot;
		p=tire[p][ch];
	}
	end[p]=1;
}
int serch(char s[])
{
	int sz=strlen(s);
	int p=1,i;
	for(i=0;i<sz;i++)
	{
		p=tire[p][s[i]-'a'];
		if(!p)  return 0;
	}
	if(!end[p])  return 0;
	use[p]++;
	if(use[p]==1)  return 1;
	return 2;
}
int gettime()
{
    time_t timep;
    struct tm *p;
    time_t now;
    time(&timep);
    p=localtime(&timep);
    now=mktime(p);
    return now;
}
int checktime()
{
    if(flag==0)
    {
        if(gettime()+15*min>=fin)
        {
            flag=1;
            return 1;
        }
    }
    if(flag==1)
    {
        if(gettime()+5*min>=fin)
        {
            flag=2;
            return 2;
        }
    }
    return 0;
}
void openpipe()
{
    memset(buf_r,0,sizeof(buf_r));
    memset(buf_w,0,sizeof(buf_w));
    if((pipe(pipe_fd))<0)
    {
        printf("Pipeline creation failed\n");
        exit(-1);
    }
}
void connection()
{
    printf("To connect, please enter: ssh s20190xxxxx@120.95.132.8 -p 6022, please make sure to wrap after input\n");
    char s[N],s1[N],s2[N],s3[N];
    memset(s,0,sizeof(s));
    memset(s1,0,sizeof(s1));
    memset(s2,0,sizeof(s2));
    memset(s3,0,sizeof(s3));
    scanf("%s%s%s%s",s,s1,s2,s3);
    strcat(s," ");
    strcat(s,s1);
	strcat(s," ");
    strcat(s,s2);
    strcat(s," ");
    strcat(s,s3);
    system(s);
}
ll getip(char s[])
{
    int i;
    ll sum=0;
    int len=strlen(s);
    for(i=0;i<len;i++)  sum=sum*1331+s[i];
    return sum;
}
int getyonghu(char s[])
{
    int ret=0,i;
    int len=strlen(s);
    for(i=5;i<len;i++)  ret=ret*10+s[i]-'0';
    return ret;
}
void back()
{
	ti--;
    tag=(fin-gettime())/min;
    fin=gettime()+60*min*24;
}
void login()
{
    connection();
//    printf("xxxx\n");
    openpipe();
    re=fork();   
    if(re<0)
    {
        printf("Failed to create child process\n");
        exit(-1);
    }
    if(re==0)
    {
        close(pipe_fd[1]);
        char s[N],s1[N],ss[N],s3[N];
        int lenss;
        memset(s,0,sizeof(s));
        memset(s1,0,sizeof(s1));
        memset(s3,0,sizeof(s3));
        memset(ss,0,sizeof(ss));
        printf("Please input again: user name, IP\n");
        scanf("%s%s",s,s1);
        strcpy(s3,s);
        if(Serch(s)!=0)
		{
			strcat(s,"?");
        	strcat(s,s1);
        	if((write(pipe_fd[0],s,strlen(s)))>0)  {}
			printf("You have handed in your paper\n");
			close(pipe_fd[0]);
//			close(pipe_fd[0]);
        	exit(0);
		}
        strcat(s,"?");
        strcat(s,s1);
        if(serch(s3)==0)  printf("This is your first login\n");
        if((write(pipe_fd[0],s,strlen(s)))>0)  {} 
        if(f[getyonghu(s3)]=getip(s1)&&f[getyonghu(s3)]!=-1)
        {
        	printf("User name does not match IP\n");
        	back();
        	close(pipe_fd[0]);
       		exit(0);
		}
//		printf("xxxxxxx\n"); 
//        if((write(pipe_fd[0],s1,strlen(s1)))>0)  {}
//        if((lenss=read(pipe_fd[0],ss,N))<0)  {}
//        printf("%s\n",ss);
//        if(strcmp(ss,"Login failed")==0)
//        {
//             back();
//             close(pipe_fd[0]);
//             exit(0);
//        }
        while(gettime()<=fin)
        {
            char s2[N];
            memset(s2,0,sizeof(s2));
            int len2;
            int nowtime=checktime();
            if(nowtime==1)   strcat(s2,"The test time is less than 15 minutes. Please take the time\n");
            if(nowtime==2)   strcat(s2,"The test time is less than 5 minutes. Please take the time\n");
            printf("%s",s2);
            getchar(); 
//            if((len2=read(pipe_fd[0],s2,N))>0)  printf("%s\n",s2);
//            sleep(min*2*1000);
            printf("If there are other operations, please enter 1, otherwise enter others\n");
            printf("If you want to see the exam notes, enter 2\n"); 
            char op[N];
            scanf("%s",op);
            if(op[0]=='1')  break;
            else if(op[0]=='2')
            {
            	printf("Please do not log in to other websites, please pay attention to the time\n");
			}
        }
        back();
        close(pipe_fd[0]);
        exit(0);
    }
    else
    {
        close(pipe_fd[0]);
//        sleep(min*1000);
        int len=0,i,len1=0,len3;
        char s[N],s1[N],ss[N],s3[N];
        memset(s,0,sizeof(s));
        memset(s1,0,sizeof(s1));
        memset(s3,0,sizeof(s3));
        memset(ss,0,sizeof(ss));
        int chose=0;
        if((len=read(pipe_fd[1],s3,N))<0) printf("The system could not read in the user name, login failed\n"),chose=1;
        len3=strlen(s3);
        for(i=0;s3[i]!='?',i<len3;i++)  s[len++]=s3[i];
        s[len]='\0';
        for(;i<len3;i++)  if(s3[i]!='?')  s1[len1++]=s3[i];
        s1[len1]='\0';
//        if((len1=read(pipe_fd[1],s1,N))<0)   printf("The system can't read IP, login failed\n"),chose=1;
        if(Serch(s)!=0)
        {
//            printf("The examinee has handed in the paper and cannot log in\n");
            chose=1;
        }
        if(serch(s)==0)
        {
//            printf("The examinee logs in for the first time and issues the test paper\n");
            insert(s);
//            system("cp C:\Users\DELL\Desktop\WEB3\第三次实习(11,13,14周)\第三次实习(11,13,14周)  /home");
            f[getyonghu(s)]=getip(s1);
        }
        else
        {
//            printf("Candidates have already logged in\n");
            if(f[getyonghu(s)]!=getip(s1))
            {
//                printf("The IP is inconsistent with the IP entered for the first time. Login failed");
                chose=1;
//                waitpid(re,NULL,0);
//                return;
            }
        }
        if(gettime()>=fin)
        {
//            printf("The test is over, candidates can't log in\n");
            chose=1;
        }
//        if(chose==1)   strcat(ss,"Login failed");
//        else  strcat(ss,"Login successful");
//        if((write(pipe_fd[0],ss,strlen(ss)))>0)  {}
        if(chose==1)
        {
            waitpid(re,NULL,0);
            close(pipe_fd[0]);
            return;
        }
        long res;
        int exitcode=0;
//        res=wait(&exitcode);
//        while(res!=-1)
//        {
//            char s2[N];
//            memset(s2,0,sizeof(s2));
//            int nowtime=checktime();
//            if(nowtime==1)   strcat(s2,"The test time is less than 15 minutes. Please take the time");
//            if(nowtime==2)   strcat(s2,"The test time is less than 5 minutes. Please take the time");
//            if((write(pipe_fd[1],s2,strlen(s2)))<0)  printf("Message transfer failed\n");
//            sleep(min*1000*2);
//            res=wait(&exitcode);
//        }
        back(); 
        waitpid(re,NULL,0);
        close(pipe_fd[0]);
        return;
    }
}
void settime()
{
    fin=gettime()+tag*min;
}
void submit()
{
    char s[N];
    getchar();
    printf("please input user name\n");
    scanf("%s",s);
    Insert(s);
    printf("submint sucessfully\n");
}
void quit()
{
    system("logout");
    printf("sucessfully\n");
}
void daemonize()
{
	pid_t pid;
	if((pid=fork())<0)  exit(-1);
	if(pid!=0)  exit(0);
	setsid();
	if(chdir("/")<0)  exit(1);
	close(0);
	open("/dev/null",O_RDWR);
	dup2(0,1);
	dup2(0,2); 
}
signed main()
{
//	daemonize();
	memset(f,-1,sizeof(f));
	fin=gettime()+60*min*ti;
    while(1)
    {
        if(gettime()>=fin)  break;
        char op[55];
        printf("1.login\n");
        printf("2.logout\n");
        printf("3.submit\n");
        printf("4.Close the exam\n");
        scanf("%s",op);
      	if(op[0]=='1')
        {
            settime();
            login();
        }
        else if(op[0]=='2')
        {
            quit();
        }
        else if(op[0]=='3')
        {
//        	settime();
            submit();
        }
        else if(op[0]=='4')  break; 
    }
    printf("The test is over\n");
    return 0;
}





评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值