⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clswskchainqueue.cls

📁 计算机网络与通信的知识
💻 CLS
字号:
VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
END
Attribute VB_Name = "clsWskChainQueue"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
'===========================================================================
'||           WinSock链表队列采用VB5提供的动态数组实现                    ||
'||                       (在服务器端用,通用)                            ||
'||                                                                       ||
'||    物理上使用一个动态数组,逻辑上为两个链表队列:使用队列和空闲队列, ||
'|| 每一个队列均为双向链表队列,表头为数组的 0 节点,数组0节点的intAfter  ||
'|| 指针指向使用队列,数组0节点的intBefore指针指向空闲队列,当这两个指针  ||
'|| 为0时,说明队列为空。                                                 ||
'||    每个队列都没有队头指针,因为预先约定为0节点,但是各有一个队尾指针。||
'||                                                                       ||
'||    该类共包括三个只读属性和三个方法:                                 ||
'||          属性 1:   WskUsedTail    返回使用队列的队尾指针             ||
'||          属性 2:   WskFreeTail    返回使用队列的队尾指针             ||
'||          属性 3:   CompressArray  是否压缩数组                       ||
'||          方法 1:  AllocateUsableWsk   分配一个可用的WinSock序号      ||
'||          方法 2:  RecycleUnUsedWsk    回收一个不用的WinSock序号      ||
'||          方法 3:  LenWskChainQueue    返回链表队列的长度             ||
'||    类中的数据独立,自成一体。                                         ||
'===========================================================================


Option Explicit
'WinSock链表队列节点数据类型
Private Type WskNode
    intBefore As Integer    '前指针
    intAfter As Integer     '后指针
    blnIsUsed As Boolean    '是否为正在使用的节点
End Type
Private WskChainQueue() As WskNode     'WinSock链表队列数组
Private intFreeTail As Integer         '空闲队列队尾指针
Private intUsedTail As Integer         '使用队列队尾指针
Private blnCompressArray As Boolean       '是否压缩数组

'####################################
' 类的只读属性,返回使用队列的队尾指针
'####################################
Property Get WskUsedTail() As Integer
    WskUsedTail = intUsedTail
End Property
'####################################
' 类的只读属性,返回空闲队列的队尾指针
'####################################
Property Get WskFreeTail() As Integer
    WskFreeTail = intFreeTail
End Property
'####################################
' 类的只读属性,返回是否压缩数组
'####################################
Property Get CompressArray() As Boolean
    CompressArray = blnCompressArray
End Property
'#######################################################
' 分配可用的 Winsock, 为类的一个方法,返回可用的节点序号
'#######################################################
Public Function AllocateUsableWsk() As Integer
Dim intTp As Integer
    intTp = UBound(WskChainQueue) + 1
    '假如空闲队列为空,则应增大动态数组的维数
    If WskChainQueueIsNull(1) Then
        ReDim Preserve WskChainQueue(intTp)
    Else
        '空闲队列出队
        intTp = WskChainQueueOut(1)
    End If
    Call WskChainQueueIn(0, intUsedTail, intTp)    '使用队列入队
    AllocateUsableWsk = intTp
End Function

'#######################################################
' 回收不用的 Winsock, 为类的一个方法
' 入口参数为不用的WinSock序号,该序号节点在未回收之前在使用队列中
'#######################################################
Public Sub RecycleUnUsedWsk(ByVal intNum As Integer)
Dim intTp As Integer
    '假如不用的WinSock序号为链表队列数组中序号最大的元素
    If intNum = UBound(WskChainQueue) Then
        Call WskChainQueueDeleteNode(intNum)   '使用队列中删除该节点
        intTp = intNum - 1
        '从该节点往回遍历,遇到空闲节点立即删除,直到遇到使用节点
        While intTp > 0 And Not WskChainQueue(intTp).blnIsUsed
            Call WskChainQueueDeleteNode(intTp)
            intTp = intTp - 1
        Wend
        '调整数组维数(变小),以便动态释放内存空间
        ReDim Preserve WskChainQueue(intTp)
        blnCompressArray = True   '压缩数组
    Else
        '使用队列中删除该节点
        Call WskChainQueueDeleteNode(intNum)
        '空闲队列中入队该节点
        Call WskChainQueueIn(1, intFreeTail, intNum)
        blnCompressArray = False  '没有压缩数组
    End If
End Sub

'###########################################
'   类的一个方法,返回链表队列的总长度
'###########################################
Public Function LenWskChainQueue() As Integer
    LenWskChainQueue = UBound(WskChainQueue)
End Function


'===========================================
' Wsk链表队列和两个队列尾指针初始化
'===========================================
Private Sub WskChainQueueInit()
    ReDim WskChainQueue(0)
    With WskChainQueue(0)
        .intBefore = 0
        .intAfter = 0
        .blnIsUsed = False
    End With
    intFreeTail = 0
    intUsedTail = 0
End Sub
'==================================================
'    Wsk链表队列  入 队
'入口参数:  intFlag    队列标志(0 表示使用队列,1 表示空闲队列)
'            intTail    相应队列的队尾指针
'            intNumIn   即将要入队的序号
'功能描述:  在相应队列的末尾添加 intNumIn 序号的节点
'===============================================
Private Sub WskChainQueueIn(ByVal intFlag As Integer, _
                            ByVal intTail As Integer, _
                            ByVal intNumIn As Integer)
    '假如队列为空
    If intTail = 0 Then
        If intFlag = 0 Then
            'WskChainQueue(0)的 后 指针应指向节点
            WskChainQueue(intTail).intAfter = intNumIn
        Else
            'WskChainQueue(0)的 前 指针应指向节点
            WskChainQueue(intTail).intBefore = intNumIn
        End If
    Else
        '队列不空时,都应该是队尾节点的后指针指向入队节点
        WskChainQueue(intTail).intAfter = intNumIn
    End If
    WskChainQueue(intNumIn).intBefore = intTail
    '任何队列的队尾节点中的后指针都设为 0,作为队尾节点标志
    WskChainQueue(intNumIn).intAfter = 0
    If intFlag = 0 Then
        '改变使用队列队尾指针和队尾元素的使用标志
        intUsedTail = intNumIn
        WskChainQueue(intNumIn).blnIsUsed = True
    Else
        '改变空闲队列队尾指针和队尾元素的使用标志
        intFreeTail = intNumIn
        WskChainQueue(intNumIn).blnIsUsed = False
    End If
End Sub

'==========================================================
'    Wsk链表队列 出 队
'入口参数:  intFlag    队列标志(0 表示使用队列,1 表示空闲队列)
'函数返回:  出队的节点序号
'功能描述:  在相应队列的队头删除一个节点,并返回该节点序号
'==========================================================
Private Function WskChainQueueOut(ByVal intFlag As Integer) As Integer
Dim intTp As Integer
    If intFlag = 0 Then
        intTp = WskChainQueue(0).intAfter
        WskChainQueue(0).intAfter = WskChainQueue(intTp).intAfter
        '假如使用队列只有一个节点,该节点出队后,队尾指针应为0,空闲队列同
        If WskChainQueue(0).intAfter = 0 Then intUsedTail = 0
    Else
        intTp = WskChainQueue(0).intBefore
        WskChainQueue(0).intBefore = WskChainQueue(intTp).intAfter
        If WskChainQueue(0).intBefore = 0 Then intFreeTail = 0
    End If
    '假如队列不只有一个节点,则下一节点的前指针应指向0节点(队头)
    If WskChainQueue(intTp).intAfter <> 0 Then WskChainQueue(WskChainQueue(intTp).intAfter).intBefore = 0
    WskChainQueueOut = intTp
End Function

'=================================================================
'    Wsk链表队列   删 除 节 点
'入口参数:  intNumIn    待删除的节点序号
'功能描述:  在相应队列中删除序号为intNumIn的节点
'=================================================================
Private Sub WskChainQueueDeleteNode(ByVal intNumIn As Integer)
Dim intTpBf As Integer, intTpAt As Integer
Dim blnTp As Boolean
    intTpBf = WskChainQueue(intNumIn).intBefore
    intTpAt = WskChainQueue(intNumIn).intAfter
    blnTp = WskChainQueue(intNumIn).blnIsUsed
    '若该节点的后指针为0,说明是队尾,需更该队尾指针
    If intTpAt = 0 Then
        If intTpBf = 0 And Not blnTp Then
            WskChainQueue(intTpBf).intBefore = 0
        Else
            WskChainQueue(intTpBf).intAfter = 0
        End If
        If blnTp Then
            intUsedTail = intTpBf
        Else
            intFreeTail = intTpBf
        End If
    Else
        If intTpBf = 0 And Not blnTp Then
            WskChainQueue(intTpBf).intBefore = intTpAt
        Else
            WskChainQueue(intTpBf).intAfter = intTpAt
        End If
        WskChainQueue(intTpAt).intBefore = intTpBf
    End If
End Sub

'===============================================
'    判断队列是否为 空
'入口参数: intFlag  队列标志(0 表示使用队列,1 表示空闲队列)
'功能描述: 若队尾指针为0(队列空),返回True,否则返回False
'===============================================
Private Function WskChainQueueIsNull(ByVal intFlag As Integer) As Boolean
Dim blnTp As Boolean
    blnTp = False
    If intFlag = 0 Then
        If intUsedTail = 0 Then blnTp = True
    Else
        If intFreeTail = 0 Then blnTp = True
    End If
    WskChainQueueIsNull = blnTp
End Function
'===============================
'  类的初始化事件
'===============================
Private Sub Class_Initialize()
    WskChainQueueInit
End Sub


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -