几年前我使用 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
一切都工作正常,但现在连接数量增加了(每秒几十个),因此软件开始出现堆栈空间不足
异常(因为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
希望这可以帮助有同样问题的人。
关于VB6 Winsock 多个 TCP 连接 > DoEvents 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37537820/