几年前,我做了一个软件,使用VB6作为TCP服务器,接收来自客户端的多个连接。VB6 Winsock多个TCP连接> DoEvents问题
的基本思想的软件是听特定端口上,接受来自不同客户端的连接,并通过每个连接到一个单独的Winsock其分析数据,看起来在DB,回复与适当的消息,然后关闭连接。
下面是一些代码:
初始化套接字应用程序启动时:
For i = 1 To MaxCon
Load sckAccept(i)
Next i
sckListen.Listen
接受连接:
Private Sub sckListen_ConnectionRequest(ByVal requestID As Long)
Dim aFreeSocket As Integer
aFreeSocket = GetFreeSocket
If aFreeSocket = 0 Then
sckAccept(0).Accept requestID
sckAccept(0).SendData "Server is full!"
sckAccept(0).Close
Else
sckAccept(aFreeSocket).Accept requestID
End Sub
接收数据,分析它,并回复:
Private Sub sckAccept_DataArrival(Index As Integer, ByVal bytesTotal As Long)
Dim sData As String
sckAccept(Index).GetData sData
'Do lots of analyizing and search in DB
'
'
sckAccept(Index).SendData "Message"
'
'
DoEvents
sckAccept(Index).Close
End Sub
一切工作正常,但现在连接的数量有所增加(夫妇几十每秒),所以软件开始得到(因为DoEvents
)Out of stack space
例外。我知道在很多情况下,DoEvents
是邪恶的,但如果我删除它,应用程序UI将不会响应(因为线程负载过重),并且某些数据可能无法传递。
所以,我的问题是:有没有人有一个想法,如何解决这个问题/不使用DoEvents
?
注:我知道VB6真的不支持多线程和可能是一个PITA用于这种情况。我实际上打算升级软件并使用.Net
重新创建它,但这需要一些时间。这就是为什么我需要在VB6中解决这个问题,因为现在该软件是用VB6编写的。
我真的不明白为什么doevents应该在dataarrival处理程序的最后一行,我会把它放在繁重的循环中。从技术上讲,doevents做了一个简单的“yield”,因此,out of stack错误可能会有另外一个来源,比如sdata的大小,我会把它放在外面的数组中,并且使用连接索引来访问它,我完全理解这很脏,但应该帮助节省一些堆。 – Gar
1-我在'DataArrival'处理程序中放置了'DoEvents',因为它触发了'Winsock.SendData',并且“如果我删除它,应用程序UI将不会响应(因为线程负载过重)并且某些数据可能会不被交付“。 2-“重载”是什么意思? 3-当出现“堆栈空间不足”错误时,堆栈将充满'sckAccept_DataArrival'事件。我假设这是因为'DoEvents'允许再次触发事件(其中包含另一个'DoEvents',等等)。 4'sData'的大小非常小(40-100字节) –
我完全理解为什么你使用了doevents,我只是没有看到它的末尾,我用来“doevents”内循环,以便循环不会锁定应用程序。即使数据量很小,您也只能获得一些空间,并且不会有任何问题。我也了解,导致你的问题的原因是堆栈中未回答的tcp查询(因为它们的处理程序正在为它们查询数据库)。 – Gar