几年前,我使用VB6制作了一个软件,它可以作为TCP服务器,接收来自客户端的多个连接。
该软件的基本理念是在特定端口上侦听,接受来自不同客户端的连接,并将每个连接传递给一个单独的winsock,该winsock分析数据,查看数据库,用正确的消息回复,然后关闭连接。
这里有一些代码:
应用程序启动时初始化套接字:
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
一切都很好,但现在连接的数量增加了(每秒几十个),所以软件开始出现Out of stack space
异常(因为DoEvents
)。
我知道在很多情况下DoEvents
是邪恶的,但如果我删除它,应用程序UI将不会响应(因为线程上的过载),并且一些数据可能无法传递。
因此,我的问题是:有人知道如何在使用/不使用DoEvents
的情况下解决这个问题吗?
注意:我知道VB6并不真正支持多线程,可能是这种情况下的PITA。实际上,我计划升级软件并使用.Net
重新创建它,但这需要一些时间。这就是为什么我需要在VB6中解决这个问题,因为该软件目前是用VB6编写的。
好吧,我设法解决了这个问题
简短答案
请勿使用DoEvents
。。有些数据不会被传递?那么,仅在SendComplete
事件中关闭连接。
长答案
第一件事:
我为什么首先使用DoEvents
?因为一些发送的消息没有送达。互联网上的许多文章/问题建议在Socket.SendData
之后使用DoEvents
,以确保数据到达接收器。
我对此进行了更深入的研究,试图弄清楚为什么这些信息没有送达。我发现这个问题只发生在发送消息后关闭连接时:
Socket.SendData "Message"
'
'
Socket.Close
因此,我只是移动了关闭与SendComplete
事件连接的行,删除了DoEvents
句子——因为我不再需要它了——问题就解决了:)
Private Sub sckAccept_SendComplete(Index As Integer)
sckAccept_Close (Index)
End Sub
我希望这能帮助到有同样问题的人。