使用winsock数组如何防止内存泄露?
一个标准的chatServer,使用winsock数组,winsock已经打过SP6Sock(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 , 网络编程