C#-JudgeSystem判题系统-判题系统

运行环境: vs2013

框架: .net4.5

上一次实验已经完成了判题核心的封装,接下来就是通过服务器后台调用判题系统对客户端传来的数据进行判断

根据前面的一些测试我们建立新的解决方案来实现完整的判题系统

首先第一步我们先确定客户端和服务器的交互流程

客户端的数据有三个:源代码,输入,输出

这时候到底怎么传到服务器的,有两个方法,一个是一次性传输,一个是分三次传输

一次性传输的话就要面临怎么切割这三种数据,必须定义一个分割符,而且数据也要面临转义的问题,到了服务器也需要进行解译,这样会消耗一定的资源

但到底这三个数据是不是一定要一次性传输呢?其实并不用,因为这三个数据作用于不同阶段并且可以单独分割开来,所以分三次传输其实是可以的,并且每个阶段都可以根据回传来判断判题的状态,出现错误是可以减少后面两次的传输,节省一定的宽带与内存

server              cilent

                        send:源代码

read:源代码

compile:源代码

send:编译结果

                        read:编译情况

                        如果成功

                        send:输入

read:输入

run:输入

send:运行情况

                         read:运行情况

                         如果程序成功运行结束未超时

                        send:输出

read:输出

比较输出

send:结果

                         read:结果

close                 close

做好流程设计后开始编码程序

由于把输入输出分离,所以类库接口需要改变适配,类库改变的成本较低,所以不采用改变调用

Unnamed QQ Screenshot20150804134628

分割实现

Unnamed QQ Screenshot20150804165614

第一步服务器读取源代码

编译,根据返回值来发送结果

Unnamed QQ Screenshot20150804165842

如果编译通过就继续向客户端读取测试输入

考虑到部分程序不需要输入所以接收到\r\n则当作无输入

所以不允许程序只那\r\n来作为测试输入,事实上也没什么意义这样的输入

虽然可以再增加一次交互来确定程序是否提供无输入测试,但这里并没有做这个操作

Unnamed QQ Screenshot20150804170611

如果能拿到结果不超时,则向客户端读取结果进行匹配

下面建立一个测试用的客户端项目

Unnamed QQ Screenshot20150804170807

客户端三次大循环往服务器发送消息

运行服务器,监听8080端口

Unnamed QQ Screenshot20150804171013

然后打开客户端进行连接

Unnamed QQ Screenshot20150804171106

然后打开客户端进行连接

Unnamed QQ Screenshot20150804171106

设置了30秒的超时

过了30秒客户端无发送数据的话,会主动关闭连接

Unnamed QQ Screenshot20150804171150

再次启动新的客户端测试

Unnamed QQ Screenshot20150804171503

语法错误的测试,会返回客户端1,代表false

Unnamed QQ Screenshot20150804171603

没有语法错误编译通过的则返回0

Unnamed QQ Screenshot20150804171916

测试第一部分通过则测试第二部分,输入部分,源程序应该输入两个数字空格,输出两个数字的和,但测试中我只输入一个数字,5秒后程序还没结束则返回false,服务器端可以看出原因是超时

启动失败比较慢测试出来,还有一种可能是正常非正常退出

Unnamed QQ Screenshot20150804172327

虽然输入是正确的,但是程序退出值不为0,当作错误处理,返回false

最后测试正确输出得到结果

Unnamed QQ Screenshot20150804172507

虽然输入正确也能得到结果了,但是不匹配,则返回false

Unnamed QQ Screenshot20150804172559

测试1+3=4可以通过,最后返回true,证明编译通过且结果正确

到此为止就完成了服务器程序的大部分功能了,而且异常机制与超时机制也可以保证服务器的运行

然后为了保证服务器的并发编译稳定性,测试程序将改成自动多线程并发执行判断结果是否通过

为了能遍历并发各种各样的情况,我把三个步骤的正确与错误做法写出用来做组合处理

Unnamed QQ Screenshot20150804181746

第一步,错误是少一个;分号

Unnamed QQ Screenshot20150804181752

第二步提供一下错误的输入

Unnamed QQ Screenshot20150804181758

第三部提供错误的结果

Unnamed QQ Screenshot20150804181804

check返回值,读取服务器的返回,0为true,1为false,每进行一步操作都要check一次看是否能匹配那次操作的返回值,不对应则为一次bug

线程函数已三个数字启动,做成字符串的形式

000代表三步为true

111代表第一步错误

011代表第二步错误

001代表第三步错误

Unnamed QQ Screenshot20150804182418

启动线程遍历四种情况,每10次启动线程读取一次bug次数

并发间隔是500ms

Unnamed QQ Screenshot20150804182418

启动线程遍历四种情况,每10次启动线程读取一次bug次数

并发间隔是500ms

Unnamed QQ Screenshot20150804181423 (1)

放置启动700次线程,理论上大部分线程都完成操作,没有发现任何的bug

后来将并发速度提升到100ms

程序运行非常快,cpu占用也到了80%左右

Unnamed QQ Screenshot20150804182714

短时间运行下是没有任何的错误,服务器和客户端都没有崩溃

在进行上千次运算后

任务管理器中并没有发现游离的进程

Unnamed QQ Screenshot20150804182926

在测试路径下发现大量的编译程序

该测试证明,服务器系统是稳健的,高并发的,并且能提供准确返回值的系统

当然这次测试是在可靠的传输环境下实现的,而在不可靠环境下或者网络环境较差的情况下,服务器只能依赖于自身的超时检测,在30秒内客户端无消息则关闭连接

在完善服务器的情况下,我们继续实现客户端的GUI化

GUI部分简单复用一下原来第一个实验的代码,但需要增加输入输出框

简单修改一下

Unnamed QQ Screenshot20150804185802

里面一下控件有必要的写上变量名

Unnamed QQ Screenshot20150804185833

所幸的是textbox控件自带换行的功能,这个可以省去类似控制台的添加换行符的复杂问题,只需要将原来的控制台的程序代码复制一下,需要的数据改成从gui获取

Unnamed QQ Screenshot20150804190051

点击ui上面的判题按钮会触发judge函数

完成后我们测试一下运行的效果

打开程序

Unnamed QQ Screenshot20150804190234

如果在没有源代码和输出的内容条件下,判题是不允许的

Unnamed QQ Screenshot20150804190629

无输入的判题(任意输入)

Unnamed QQ Screenshot20150804190809

服务器关闭的情况下

Unnamed QQ Screenshot20150804190913

会显示服务器连接错误

Unnamed QQ Screenshot20150804190957

源代码少一个分号,显示编译错误

Unnamed QQ Screenshot20150804191100

不进行正确输入,服务器会显示超时处理,客户端会显示错误的输入

Unnamed QQ Screenshot20150804191154

输入正确则判断结果,结果不正确则输出错误的结果

Unnamed QQ Screenshot20150804191232

结果正确,自然进入接受状态

对此已经完成客户端的基本功能,当然再错误的输入或者在算法复杂度较高的运算中,服务器未能够做出及时的相应,这时候就要做线程处理可以避免程序在等待过程中表现的卡死现象,暂时不去实现这是优化性的功能,到此整个实验已经进行完毕

通过最后一个综合实验,整合每个实验的内容,完善服务器功能与客户端的使用,在实验过程中,对于服务器的稳健性等做了更深层的探索,而客户端部分还有一些线程级别的优化并没有进行,有待实现,从开始的设计到各个部分的调整,也体会到知识综合应用的重要性,在这一次实验中并没有过多新知识的掌握,更重要的是接口与测试部分的实现

转载于:https://my.oschina.net/tmj1993/blog/494684

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
BNUEP Offline Judge 北京师范大学珠海分校离线评测系统是在具备题目测试数据的情况下,能无联网自动评测ACM/ICPC模式的源代码评测系统(即本地测试工具、评测机)。它主要有以下功能(所有的功能都无需联网,在本机即可实现): *评测核心功能: 基本具备Online Judge判题核心功能,如编译代码、内存限定,时间限定,获取代码长度等; *支持多种语言: 1.0 Beta2版本支持C/C++、Pascal、C#、JAVA; *出题模式 可以在有标准输入数据和标准程序的情况下,由系统产生标准输出数据,并可批量保存,同时自动命名标准输出数据的后缀; *文本高亮对比 在判题后,可以直接在本系统中将自己的程序输出和标准输出进行高亮的文本差异对比,操作类似于一些文本对比软件,在一定程度上可以较方便地发现WA代码的出错细节; *支持不限时执行代码 这个功能可以在一定程度上检测TLE代码的算法是否正确的,当然,不能是跑一天都没跑出来的程序; *打包与加密测试数据 使用加密后的数据可以正常判题,但不显示标准输出。这个功能是为了弥补放出去给别人评测的测试数据是明文的缺陷。加密之后评测方就看不到测试数据。这样就既可以实现离线评测,又可以实现Online Judge上的对测试数据屏蔽; ACM-ICPC简介: ACM国际大学生程序设计竞赛(简称ACM-ICPC)是由国际计算机界具有悠久历史的权威性组织ACM学会(Association for Computing Machinery)主办,是世界上公认的规模最大、水平最高、参与人数最多的大学生程序设计竞赛,其宗旨是使大学生能通过计算机充分展示自己分析问题和解决问题的能力。 ACM-ICPC的每一道题,都具备题目、需求描述、输入格式描述、输出格式描述、样例输入和样例输出共六大信息,有些题目还有一定的提示。此外,裁判还额外存储了关于该题的一组或多组对选手屏蔽的标准输入和标准输出数据,这些测试数据已经经过验证符合题意要求。当用户提交一道题目的源码之后,裁判会将该源码放入评测系统中编译运行,并使用标准输入作为用户程序的输入,然后获取用户程序的输出,接着,将用户程序输出和标准输出比较,最后返回给用户一个评判结果。评判结果包括:Accepted(测试通过)、Compile Error(编译失败)、Memory Limit Exceed(内存超出限制)、Presentation Error(格式错误)、Runtime Error(运行时错误,可能是数组越界,改写只读的内存,除零,栈或堆溢出等错误)、Time Limit Exceed(时间超出限制)、Wrong Answer(答案错误)等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值