作者: 杨家成
大多数计算机考试需要进行机试(如
计算机等级考试),在机试中会碰到如何给考生分发试卷及回收答卷等问题。一般的解决方案是: 采用软盘;在服务器上建立考生文件夹,设置登录密码或进行登录限制;基于文件夹共享,以文件复制方式实现发卷、交卷。这些方案在实施过程中都存在不少问题,如软盘的意外损坏; 工作量太大,操作太烦琐; 共享出来的交卷文件夹可能被考生识破而导致安全隐患等等。相比而言, 采用基于Winsock的文件传输方式进行发卷、交卷可以在一定程度上解决这个
问题。实践证明,这是一个行之有效的方案,本文针对这一方案进行介绍。
编程思路
本系统的基本思路是: 在局域网环境下,考试前把各卷别的考试文件分别压缩,放在服务器的某个文件夹中,服务器端执行服务器程序,负责接收考生的请求并做出响应。各考生执行客户端
程序,先通过其中的发卷模块向服务器请求把考试文件发送到考生的本地硬盘,考试完成后再通过其中的交卷模块把答案发送回服务器。由于文件的发送是基于TCP协议的端口通信,考生无从知道试题及
答案放在哪里,很好地解决了安全问题。下面是本系统实现过程中的一些关键问题:
1. 多连接的实现
由于有多个考生参加考试,每个考生都要与服务器建立一个连接,为此在服务器
程序中采用动态建立多连接,即采用Winsock控件数组。
2.数据类型
发送的数据类型通常有字串流(String)和字节流(Char数组)两种。前者一般用于发送辅助信息,如文件大小、考生信息等,后者用于发送文件正文。
3. 发送、接收结束的判断
每进行一次发送(或接收)后,将已发送(或已接收)的字节数与源文件的大小进行比较,判定是否结束。
4.文件夹的发送
Winsock控件只能发送文件,但考试中常常包含文件夹。怎么办?办法是先在
程序中调用压缩软件将其压缩成单个文件再发送,接收方在接收完后进行解压缩还原。这是本系统的一个关键思路。
5.等待压缩/解压缩的完成
由于压缩/解压缩程序是通过VB的Shell函数调用执行的,而Shell是以异步方式执行压缩/解压缩程序的,这样就会出现没等压缩/解压缩完成,
vb代码继续往下执行的情况。为此需要借助OpenProcess、GetExitCodeProcess这两个Windows API,通过循环读取进程状态值控制
程序的等待。
6.注意事项
发送方在发送数据时采用间歇方式,否则易造成客户端数据丢失,通常的做法是执行VB的DoEvents语句。接收方在接收期间不能出现与用户进行交互的等待状态,否则会耽误接收,造成数据丢失。
服务器端接收考生交卷时,应接收完所有考生的压缩文件后,再统一进行解压缩,否则会加重服务器的负担。
7.
程序流程
客户端程序、服务器
程序的流程图分别如图1、图2所示:
关键代码
1.建立保存考生信息的数据类型
先在服务器
程序的标准模块中创建一个用于存放每个连接有关信息(每个连接对应一个考生)的自定义数据类型ClientConn:
Public Type ClientConn
Recvd As Boolean ’是否已接收过数据
FileNum As Integer ’文件号
FinishSize As Double ’完成收发的字节数
FileSize As Double ’文件的大小
Gh As String * 6 ’交卷者的考号
Jb As String * 1 ’交卷者的卷别
End Type
在服务器
程序窗体模块中声明一个用于记录所有连接信息的模块级动态数组Conns:
Dim Conns() As ClientConn
2.服务器端建立连接:
Private Sub wisServer_ConnectionRequest(Index As Integer, ByVal requestID As Long)
If Index = 0 Then
Conncount = Conncount + 1
’连接总数,为模块级变量
Load wisServer(Conncount)
’服务器端WinSock控件数组
ReDim Preserve Conns(1 To Conncount)
wisServer(Conncount).LocalPort = 0
wisServer(Conncount).Accept requestID
End I