超小型在线评测系统的设计与实现

2018-06-13 07:52黄金春杜娟娇
现代计算机 2018年13期
关键词:表单代码服务器

黄金春,杜娟娇

(1.广西中医药大学图书馆信息技术部,南宁 530021;2.广西中医药大学第一附属医院教学部,南宁 530001)

0 引言

随着社会的高度发展,信息技术应用到了社会生活的方方面面,也促使更多的学生投身到信息技术开发的工作中,而程序设计能力作为最重要的开发能力,也日益成为了各个专业学生的学习要求。提高程序设计的能力需要大量的编程实践练习,因此很多学校都开发了源代码在线评测系统(Online Judge下称OJ系统)以用来提高学生的程序设计水平。但传统的OJ系统都比较庞大,需要安装Web服务器还需要安装数据库服务器,非常不方便在日常的教学中使用,本文提出一种不需要搭建Web服务器也不需要搭建数据库服务器的超小型OJ系统,并具体论述系统的实现。

1 系统基本架构

超小型OJ系统虽然不需要Web服务器以及数据库服务器,但是同样实现Web服务和数据库服务功能。系统Web功能基于Java的HTTP Server API开发,这些API主要实现了HTTP协议,HTTP协议是最为流行的网络协议由请求与应答协议构成,最主要使用是HttpServer类、HttpHandle接口。HttpServer类实例实现监听客户端的请求,然后HttpServer会调用HttpHandler接口实现类的回调方法来处理客户端请求。数据库功能采用Sqlite3系统来实现,该数据库非常小巧,仅为一个文件,复制这个文件即可使用。

2 系统实现

2.1 建立监听,区分请求

在OJ系统中主要存在两种请求,分别为题目请求(显示题目以及提供写程序的表单)和程序提交请求(完成对提交的程序进行编译、运行、检测运行结果等工作)。因为无Web服务器,无法使用不同网页来区分请求。但是可以巧妙地使用HttpServer类的create-Context方法虚拟出不同请求来区分,具体设计是该方法有个上下文参数,构造不同参数即可实现区分不同请求,然后再调用HttpHandler接口实现类来处理请求。具体代码如下:

HttpServer httpserver=provider.createHttpServer(new InetSocketAddress(6666),100);//监听

httpserver.createContext("/",new MyHttpHandler());//跟 文 件夹,表示题目请求。

httpserver.createContext("/hjc2",new SHttpHandler());//hjc2

文件夹,表示程序提交请求

……

static class MyHttpHandler implements HttpHandler{//对第一种请求响应

……}

static class SHttpHandler implements HttpHandler{//对第二种请求响应

特别说明的是,代码里提到hjc2文件夹,但其实并不存在这个文件夹,仅作为区分请求使用。

2.2 实现题目请求

在OJ系统中,要实现的第一个请求即为题目显示请求。其流程如图1所示。

图1 题目请求流程

从示意图看出题目请求由两个响应内容合成,一为显示某个题目的内容与要求,另一个为显示提供学生做题的表单。题目内容从数据库中读取,用一字符串变量保存,此处涉及数据库读取等Java操作本文不论述,要指出的是为了保持系统小型化的特色,选用Sqlite3之类的小型数据库。表单的显示比较简单,因其为静态内容只要预先建立好htm文件用代码读取文件即可,要注意的是表单提交的action域必须是含有hjc2的路径,以便表单提交后作为第二种请求处理。类似:

。该部分代码如下:

static class MyHttpHandler implements HttpHandler{

public void handle(HttpExchange httpExchange)throws IOException{

String responseMsg="";//响应信息

responseMsg=getFromDb();//从数据库读取内容

responseMsg=responseMsg+”

”+getFromHtm();//从htm文件读取内容

byte[]bs=responseMsg.getBytes();

httpExchange.sendResponseHeaders(200,bs.length);//设置头属性及响应信息的长度

OutputStream out=httpExchange.getResponseBody();//获得输出流

out.write(responseMsg.getBytes());//发给客户端

2.3 实现程序提交请求

该请求为重要的请求。实现比较复杂,分为主线程和定时器线程两个流程,流程图示如图2所示。

图2 提交处理流程

其中主线程主要完成在线编译,在线输入测试数据,在线执行以及输出做题反馈等功能。定时器线程是起到防止程序执行时无休止地运行,比较简单,在此仅介绍主线程的实现。

(1)在线编译实现

在日常的程序设计中,都是使用IDE环境进行程序的编译以及运行。其实无论对于C++源程序还是Java源程序还有命令行编译模式,如Java命令行编译为执行Javac XX.java的命令,在线编译则必须要运行编译命令。在java环境下,可以使用Runtime类exec方法来实现运行外部命令,Runtime类封装了运行时的环境。每个Java应用程序都有一个Runtime类实例,使应用程序能够与其运行的环境相连接。为了对执行的程序进行控制,不但需要Runtime类,还需要Process类,Runtime类的exec()方法返回一个Process对象,可以使用这个对象控制Java程序与新运行的进程进行交互。这两个类是实现主线程里功能重要的类,后面还会使用到。实现在线编译的代码如下:

Runtime sr;

Process p;//Process类对象

String cmd,fdata;

sr=Runtime.getRuntime();//获取 Running 类实例

cmd="javac c:\users\hjc\documents\oj\C"+stuid+"_"+subjectid+".java";

try{

p=sr.exec(cmd);//执行编译并返回Process类对象

(2)编译的输出信息及在线输入测试数据

要实现获取编译输出信息,以便进行反馈,普通情况下可以使用javac……>>rs.txt等DOS下常用的输出重定下方法。但在线方式下这方法不行,很多设计都采用管道,在此采用流来实现。但要注意使用什么流,先看流示意图。

图3 外部程序与OJ系统流示意图

从示意图可以看出,为了获得外部编译程序的输出,采用的是输入流而不是输出流,而如果要向外部程序输入信息则采用输出流。使用Process对象的getInputStream()方法或者getErrorStream()方法返回输入流,其中getInputStream()返回外部程序的正常输出,而get-ErrorStream()方法返回是错误输出。在OJ设计里编译部分只关心的是编译错误,使用错误流。获取编译信息的代码如下:

InputStream fis=p.getErrorStream();//取得错误结果的输出流

InputStreamReader isr=new InputStreamReader(fis);//用 一 个

读输出流类封装

……Read读流的内容

在线输入测试数据的设计和获取编译错误的设计类似,但是使用的是输出流。代码如下:

OutputStream fin=p.getOutputStream();//取得输入流

File f=new File("c:\users\hjc\documents\oj\T\t"+subjectid+".data");//测试数据文件

……Writer写入流

(3)执行时间与内存使用量

在反馈信息中,还有一项重要的内容是要获取程序执行的时间及内存使用字节数。获取执行时间比较简单,分别在程序开始和结束时各获取一次时间,然后计算两次时间差即可。获取内存可以使用Runtime类的 freeMemory()方法,如:sr.freeMemory(),也分别在程序开始和结束时各获取一次,然后计算差值。要注意的是在开始时最好使用sr.gc()方法先清理一次内存,这样可以获取地更为准确。

(4)程序控制

在OJ设计中还要对提交程序的执行进行控制。提交的程序可能会含有死循环、破坏性代码等各种问题,如果不对程序加以控制,很容易造成严重的后果。程序控制主要从两方面进行,一为运行时间控制,二为运行安全控制。

运行时间控制采用定时器和Process类同时控制的方式,具体设计是在程序执行前,先启动定时器线程,定时3秒,如果程序能在3秒内结束则认为程序是合理的运行,如果程序超过3秒,则利用Process类的destroy方法强制停止程序运行,并返回超时结果。

安全运行控制。这部分设计在很多OJ系统中基本使用C++开发调用系统内核函数来实现(基于Linux的ACM在线评测系统研究),设计的较为复杂。Java在JDK1.6后提供了一个安全管理器,可以对执行的Java程序进行多方面的限制(该内容较多在此不论述),设计好限制文件后,在运行时加入限制参数-Djava.security.manager即可以实现限制模式下运行。

3 结语

计算机程序设计能力作为当今信息社会的一种重要能力愈发得到学生们的重视,OJ系统是提高学生设计能力的一种重要工具。本文介绍了一种小型的OJ系统实现,实践表明该系统非常小,既不需要安装Web系统也不需要安装数据库系统,仅有几个文件完全可以放置在U盘里带着走,但该系统却可以实现大型OJ系统的主要功能。系统非常适用于课堂上课,机房临时小型测验等需要快速部署的场所,具有非常强的实用性。

[1]黄金春等.编写Web服务器远程查看MySQL数据[J].信息系统工程,2009(187).

[2]ITeye博客.JDK6新玩具——HttpServer的使用[EB/OL].http://sunnylocus.iteye.com/blog/460945.

[3]51CTO博客.深入研究java.lang.Runtime类[EB/OL].http://blog.51cto.com/lavasoft/15565.

[4]蔡崇超.基于Web的在线判题系统设计与实现[J].软件导刊,2016(15)3.

[5]Oracle Help Center.Class SecurityManager[EB].https://docs.oracle.com/javase/7/docs/api/java/lang/SecurityManager.html.

猜你喜欢
表单代码服务器
移动App表单组件体验设计
PowerTCP Server Tool
BlackJumboDog
2018年全球服务器市场将保持温和增长
浅谈网页制作中表单的教学
神秘的代码
使用智能表单提高工作效率
一周机构净增(减)仓股前20名
一行代码玩完19亿元卫星
近期连续上涨7天以上的股