当前位置:编程学习 > VB >>

使用winsock数组如何防止内存泄露?

一个标准的chatServer,使用winsock数组,winsock已经打过SP6

Sock(0)监听
Sock(1)~Sock(1024)用于Accpect客户端的连接

尝试一下两种方法,均在压力测试下发生内存泄露

方法1:
初始化直接 load Sock(1)-Sock(1024),有连接直接寻找一个空闲的连接上,关闭的时候close连接

方法2
有新连接的时候 load Sock(freeID),连接关闭的时候 unload Sock(useID)

请教高人如何防止内存泄露? --------------------编程问答-------------------- 关注~ --------------------编程问答-------------------- 请高人指教 --------------------编程问答-------------------- 感觉第一种方法效率更高
lz的描述和内存泄漏没有甚么关系。。。

估计不是由于socket的使用造成的 --------------------编程问答-------------------- 该回复被版主删除 --------------------编程问答-------------------- 服务端除了常规的soket以外也没有其他代码了
压力测试的环境是使用FlashSokcet模拟客户端,不间断的连接和发送数据,服务器端负责接受并广播.大致约有80个并发连接,每个连接间隔2秒发送一个数据,服务器端即时广播给全部的客户端.
符上服务器端代码:

Private Sub Form_Load()
    MaxSockID = 1024
    
    Dim i
    For i = 1 To MaxSockID
        
        Load SOCK(i)
        
        Socks(i).IsConnent = False
        Socks(i).UserName = ""
    Next
    
    SOCK(0).LocalPort = 8798
    SOCK(0).Listen
End Sub

Private Sub SOCK_ConnectionRequest(Index As Integer, ByVal requestID As Long)
    If Index = 0 Then
        Dim FreeSockID
        FreeSockID = GetFreeSockID()
        SOCK(FreeSockID).Accept (requestID)
        Socks(FreeSockID).IsConnent = True
    End If
End Sub

Function GetFreeSockID()
    For i = 1 To MaxSockID
        If Not Socks(i).IsConnent Then
            GetFreeSockID = i
            Exit Function
        End If
    Next
End Function

Private Sub SOCK_DataArrival(Index As Integer, ByVal bytesTotal As Long)
    On Error GoTo e:
    Dim ReData As String
    SOCK(Index).GetData ReData, vbString
    
    ReData = Replace(ReData, "|$|", "%u")
    If Asc(Right(ReData, 1)) = 0 Then ReData = Left(ReData, Len(ReData) - 1)
    
   ' Text1.Text = Text1.Text & ReData
    
    Dim ReDatas
    ReDatas = Split(ReData, "|")
    '登陆
    If (ReDatas(0) = "1") Then
        Socks(Index).UserName = ReDatas(1)
        SOCK(Index).SendData "1|" & Index & "|" & ReDatas(1) & Chr$(0)
        DoEvents
    End If
    
    '保持在线
    If (ReDatas(0) = "2") Then
        Socks(Index).LastUpdateTime = Now()
    End If

    '取得在线用户列表
    If (ReDatas(0) = "3") Then
        Dim UL
        For i = 1 To MaxSockID
            If Socks(i).IsConnent Then
                UL = UL & Socks(i).UserName & "|" & i & "|"
            End If
        Next
        If UL <> "" Then UL = Left(UL, Len(UL) - 1)
        SOCK(Index).SendData "3|" & UL & Chr$(0)
        DoEvents
    End If

    '广播
    If (ReDatas(0) = "4") Then
        For i = 1 To MaxSockID
            If Socks(i).IsConnent Then
                SOCK(i).SendData "4|" & Index & "|" & Socks(Index).UserName & "|" & ReDatas(1) & Chr$(0)
                DoEvents
            End If
        Next
    End If
    
    '私聊  5|handle1|name1|handle2|name2|something
    If (ReDatas(0) = "5") Then
        Dim FromID
        Dim FromName
        Dim ToID
        Dim ToName
        Dim Message
        ToID = ReDatas(1)
        ToName = ReDatas(2)
        Message = ReDatas(3)
        
        '如果没有指定ToID
        If ToID = "" Then
            For i = 1 To MaxSockID
                If Socks(i).IsConnent Then
                    Dim iName
                    iName = Trim(Socks(i).UserName)
                    If iName = ToName Then
                        ToID = i
                    End If
                End If
            Next
        End If
        
        If ToID <> "" Then
            '5|fromID|fromName1|something
            SOCK(ToID).SendData "5|" & Index & "|" & Socks(Index).UserName & "|" & Message & Chr$(0)
            DoEvents
        End If
    End If
    
e:

End Sub
Private Sub SOCK_Close(Index As Integer)
    If Index = 0 Then
        SOCK(0).Close
        SOCK(0).Listen
    Else
        SOCK(Index).Close
        Socks(Index).IsConnent = False
    End If
End Sub

Private Sub SOCK_Error(Index As Integer, ByVal Number As Integer, Description As String, ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean)
    If Index = 0 Then
        SOCK(0).Close
        SOCK(0).Listen
    Else
        SOCK(Index).Close
        Socks(Index).IsConnent = False
    End If
End Sub --------------------编程问答-------------------- Socks(FreeSockID).IsConnent
Winsock控件有这个属性么?
我怎么查不到,只查到是根据State属性判断状态,而且该属性只读 --------------------编程问答-------------------- 忘记了还有一个模块
================================================

Public MaxSockID

Type cSock
    IsConnent As Boolean
    UserName As String
    LastUpdateTime As Date
End Type

Public Socks(1024) As cSock --------------------编程问答-------------------- ............................................................ --------------------编程问答-------------------- 连接断开的时候没必要卸载Winsock,可能你这边刚刚卸载客户端又过来一个请求,效率不太好。你可以试试用一个列表来保存闲置的Winsock,收到新的连接请求时先去闲置列表里取,如果有,取一个出来使用然后从列表中移除,如果没有的话再创建新的。当有连接断开时不要直接卸载,而是关闭后放入列表里待用。程序关闭时再一次性将列表里的Winsock卸载。

你可以用集合来模拟列表,每次只需要判断Collection.Count即可知道有多少空闲的,取的时候取第一个就行。 --------------------编程问答-------------------- 我的方法即不用一次加载很多Winsock,也不用循环去找空闲的。 --------------------编程问答-------------------- 你怎么知道内存泄露了?????? --------------------编程问答-------------------- 应该是堆栈溢出吧? 我就遇到这个错误,主要是客户端通过循环把文件以byte数组方式传到服务器端,服务器收到后用winsock.senddata 发送给客户端结果,可是经常发布出去结果就堆栈溢出了
注:winsock.senddata 后面都跟了doevents --------------------编程问答-------------------- 说了多少遍了,winsock开发根本就不用使用doevents也能完美的运行。
关键是设计思路正确。 --------------------编程问答-------------------- 请问这个程序的功能是什么
运行之后什么都没有啊
在窗体上应该放哪些控件
请高手指教 --------------------编程问答-------------------- 我用的是你说的方法一 首先建立了4000个控件 然后谁来了就用一个 不用了就close  稳定在800连接 接收数据21.9KB/s 发送数据1.51KB/S的时候 内存占用20多M 但是差不多每几分钟 内存涨大概4KB或者8KB 长到多少还在测试中 先来发个帖子 
补充:VB ,  网络编程
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,