5.1 服务器端设计
5.1.1 服务器端Winsock控件
Winsock控件是一个在运行中不可见的控件,所以当程序运行时,主界面并不显示它,而只是在后台运作。Winsock控件对Winsock API进行了封装,屏蔽了用Winsock编写TCP/IP应用的细节,使用时不必了解TCP/IP具体内容和如何调用Winsock API,所以使用起来非常方便,只要设置好相应属性,在一些触发事件过程中做好相应的处理,就能实现网络应用程序的编写。
在本系统中服务器会分别给不同的客户端安排不同的Winsock连接,每当有新的客户请求连接时,服务器首先检验是否有空闲的Winsock控件来接受请求,有就用空闲Winsock来接受请求,不然服务器会动态生成新的Winsock控件,然后用新生成的控件请求。当Winsock控件数组接收到数据时,先将数据按间隔的逗号分开,提取帧头和类型,并对数据内容分别做相应的处理。当网络连接关闭时,要找到网络连接列表中相应的记录,将网络连接状态显示为“断开”。另外,在利用sock发送数据之前一定要检验sock连接状态,否则当sock连接不是连接状态时,系统会出错。下面来看一下该控件的一些事件代码。
1. Winsock触发Close事件:
Private Sub SockToCln_Close (index As Integer) '网络连接关闭
Dim i As Integer
Dim FindItm As ListItem
For i = 1 To ClMax
If Client (i). index = index Then '找到该连接
Set FindItm = Me.LvCnn.FindItem (Client (i). UsrID)
FindItm.SubItems(1) = "断开"
FindItm.SubItems (2) = Now
Exit For
End If
Next i
End Sub
2. Winsock触发ConnectionRequest事件:
'接受连接请求
Private Sub SockToCln_ConnectionRequest (index As Integer, ByVal requestID As Long)
Dim i As Integer
For i = 1 To MaxSvrSock '查询是否有关闭的空闲控件
If SockToCln(i).State = sckClosed Then
SockToCln(i).LocalPort = 0
If SockToCln(i).LocalPort = SvrPort Then '不能占用侦听端口
Exit Sub
End If
SockToCln(i).Accept requestID
Exit Sub
End If
Next i
'没有空闲的控件,原有socket都被占用,需要新增Winsock
MaxSvrSock = MaxSvrSock + 1 '控件数增加
Load SockToCln(MaxSvrSock) '动态生成一个winsock控件
SockToCln(MaxSvrSock).LocalPort = 0 '设置新端口
SockToCln(MaxSvrSock).Accept requestID '接受连接请求
End Sub
3. Winsock触发DataArrival事件:
'接受并处理数据
Private Sub SockToCln_DataArrival (index As Integer, ByVal bytesTotal As Long)
Dim StrArrival As String, StrGet () As String
Dim strBack As String
Dim RdrID As String
Dim bkNum As Long
Dim StatNum As Integer
Dim UsrID As String
Dim UsrPwd As String
Me.SockToCln (index). GetData StrArrival, vbString '接受数据
If Len (StrArrival) < 1 Then
Exit Sub
StrGet () = Split (StrArrival, ",", -1) '拆分接收到的数据
Select Case StrGet(0) '判断类型
Case "Lend" '图书借阅
RdrID = StrGet (1) '得到RdrID
bkNum = Val (StrGet (2)) '得到BkNum
strBack = CheckLend(RdrID, bkNum) '回复客户端
Case "Return" '图书归还
bkNum = Val (StrGet (1)) '得到BkNum
strBack = CheckReturn (bkNum) '回复客户端
Case "Pay" '缴纳欠款
RdrID = StrGet (1) '得到RdrID
strBack = CheckPay (RdrID) '回复客户端
Case "Type" '操作图书类别
'调用BookType函数处理图书管理命令
strBack = BookType (StrGet, index)
Case "Book" '图书管理
'调用BookInfo函数处理图书管理命令
strBack = BookInfo(StrGet, index)
Case "Rdr" '读者管理
'调用Reader函数处理图书管理命令
strBack = Reader (StrGet, index)
Case "Usr" '管理员管理
'调用User函数处理图书管理命令
strBack = User (StrGet, index)
Case "Stat" ‘借阅统计管理
StatNum = Val (StrGet (1)) '得到StatNum
strBack = CheckStat(StatNum) '回复客户端
Case "Cnn" '连接信息
UsrID = StrGet (1) '得到UsrID
UsrPwd = StrGet(2) '得到UsrPwd
strBack = CheckUsr (UsrID, UsrPwd, index) '回复客户端
End Select
If Me.SockToCln (index).State <> sckConnected Then '检验sock连接
Exit Sub
End If
Me.SockToCln (index).SendData strBack '发送返回信息
End Sub
5.1.2 服务器端公共模块设计
启动Visual Basic 6.0后,新建一个标准EXE工程,然后将该工程保存,选择保存路径,并命名为图书馆管理系统服务器工程。
接着给该工程添加一个模块。选择菜单[工程]、[添加模块]命令,此模块中定义服务器端需要用到的公共变量和公共类型。下面是代码的实现过程。
'定义全局ADO对象连接,用于连接数据库
Public DBCnn As New ADODB.Connection
'现存动态生成的Winsock控件数(不包括静态生成的那个保持帧听的控件)
Public MaxSvrSock As Integer
Public SvrPort As String '服务器端口
Public Client (1 To 100) As ClType '允许连接100个客户端
Public ClMax As Integer '记录客户端连接最大下标
Type ClType'定义客户端类型
UsrID As String '管理员ID
index As Integer '通道号
End Type
5.1.3 服务器端主界面预览
5.2 客户端设计
5.2.1 客户端代码设计
1. MDIForm_Load过程和MDIForm_Unload过程
Private Sub MDIForm_Load ()
If App.PrevInstance Then '确定该程序没有被启动过
MsgBox "您已经启动过了本程序!"
End
End If
End Sub
Private Sub MDIForm_Unload (Cancel As Integer)
If Me.SockToSvr.State <> sckClosed Then '检查Winsock连接是否关闭
Me.SockToSvr.Close
End If
End Sub
2. 客户端Winsock触发事件过程
Close 过程
Private Sub SockToSvr_Close()
'状态栏显示服务器状态
MDIFrm.StatusBar1.Panels(1).Text = "服务器连接状态:断开。"
End Sub
Connect过程
Private Sub SockToSvr_Connect() '连接服务器
Dim str As String
'向服务器发送请求数据=Cnn,Usr_ID,Usr_Pwd
str = "Cnn," & UserNow.ID & "," & UserNow.Pwd & ","
'检验sock连接并向服务器发送数据
If MDIFrm.SockToSvr.State <> sckConnected Then
MsgBox "还没有连接数据库,不能发送请求!"
Exit Sub
End If
Me.SockToSvr.SendData str
End Sub
DataArrival过程
Private Sub SockToSvr_DataArrival(ByVal bytesTotal As Long)
Dim StrArrival As String, StrGet() As String
Dim Start As Integer
Dim i As Integer, j As Integer, k As Integer
Dim LtItm As ListItem
'接收数据,String类型
Me.SockToSvr.GetData StrArrival, vbString
If Len(StrArrival) < 1 Then
Exit Sub
'拆分接收到的数据
StrGet() = Split(StrArrival, ",", -1)
'得到帧头,按不同类型做响应的处理
Select Case StrGet(0)
'用户管理
Case "Usr"
'按类型处理
Select Case StrGet(1)
'添加管理员
Case "01"
'状态栏显示服务器状态
MDIFrm.StatusBar1.Panels(1).Text = "服务器连接状态:响应添加管理员。"
'弹出提示框提示用户
MsgBox StrGet(2), , "服务器响应"
'删除管理员
Case "02"
'状态栏显示服务器状态
MDIFrm.StatusBar1.Panels(1).Text = "服务器连接状态:响应删除管理员。"
'弹出提示框提示用户
MsgBox StrGet(2), , "服务器响应"
'查询管理员
Case "03"
'状态栏显示服务器状态
MDIFrm.StatusBar1.Panels(1).Text = "服务器连接状态:响应查询管理员。"
'清空列表
FrmUsrQuery.ListUsrResult.Clear
'在列表中显示查询结果
For i = 0 To UBound(StrGet) - 2
FrmUsrQuery.ListUsrResult.AddItem StrGet(i + 2)
Next i
End Select
'读者管理
Case "Rdr"
'按类型处理
Select Case StrGet(1)
'添加读者
Case "01"
MDIFrm.StatusBar1.Panels(1).Text = "服务器连接状态:响应添加读者。"
MsgBox StrGet(2), , "服务器响应"
'删除读者
Case "02"
MDIFrm.StatusBar1.Panels(1).Text = "服务器连接状态:响应删除读者。"
MsgBox StrGet(2), , "服务器响应"
'查询读者
Case "03"
MDIFrm.StatusBar1.Panels(1).Text = "服务器连接状态:响应查询读者。"
FrmRdrQuery.ListRdrResult.Clear
For i = 0 To UBound (StrGet) - 2
FrmRdrQuery.ListRdrResult.AddItem StrGet (i + 2)
Next i
End Select
'图书类型信息
Case "Type"
Select Case StrGet(1)
'添加图书类型
Case "01"
MDIFrm.StatusBar1.Panels(1).Text = "服务器连接状态:响应添加图书类型。"
MsgBox StrGet(2), , "服务器响应"
'删除图书类别
Case "02"
MDIFrm.StatusBar1.Panels(1).Text = "服务器连接状态:响应删除图书类别。"
MsgBox StrGet(2), , "服务器响应"
'查询图书类型
基于cs模式的图书管理系统^论文论文(五)由免费论文网(www.jaoyuw.com)会员上传。