VB6 Winsock 多个 TCP 连接 > DoEvents 问题
VB6 Winsock multiple TCP connections > problems with DoEvents
几年前我用 VB6 做了一个软件,它作为 TCP 服务器,接收来自客户端的多个连接。
该软件的基本思想是在特定端口上监听,接受来自不同客户端的连接,并将每个连接传递给单独的 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
一切正常,但现在连接数增加了(每秒几十个),所以软件开始出现 Out of stack space
异常(因为 DoEvents
)。
我知道在很多情况下 DoEvents
是邪恶的,但如果我删除它,应用程序 UI 将不会响应(因为线程上的过载)并且一些数据可能未发货。
所以,我的 问题 是:有人知道如何使用 DoEvents
解决这个问题 with/without 吗?
注意:我知道 VB6 并不真正支持多线程,对于这种情况可能是一个 PITA。我实际上正计划升级软件并使用 .Net
重新创建它,但这需要一些时间。这就是为什么我需要在 VB6 中解决这个问题,因为现在该软件是用 VB6 编写的。
好吧,我设法弄清楚了问题,并且已经解决了。
简答
不要使用DoEvents
..有些数据不会传送?那么,仅在 SendComplete
事件中关闭连接。
长答案
第一件事:
为什么我首先使用 DoEvents
?因为某些 sent 邮件没有送达。网上很多articles/questions建议在Socket.SendData
之后使用DoEvents
,以保证数据到达接收方。
我对此进行了更深入的研究,试图找出邮件未送达的原因。我发现这个问题只有在发送消息后关闭连接时才会出现:
Socket.SendData "Message"
'
'
Socket.Close
所以,我只是将关闭连接的行移到 SendComplete
事件,删除了 DoEvents
句子 - 因为我不再需要它了 - 问题就消失了: )
Private Sub sckAccept_SendComplete(Index As Integer)
sckAccept_Close (Index)
End Sub
希望对遇到同样问题的人有所帮助。
几年前我用 VB6 做了一个软件,它作为 TCP 服务器,接收来自客户端的多个连接。
该软件的基本思想是在特定端口上监听,接受来自不同客户端的连接,并将每个连接传递给单独的 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
一切正常,但现在连接数增加了(每秒几十个),所以软件开始出现 Out of stack space
异常(因为 DoEvents
)。
我知道在很多情况下 DoEvents
是邪恶的,但如果我删除它,应用程序 UI 将不会响应(因为线程上的过载)并且一些数据可能未发货。
所以,我的 问题 是:有人知道如何使用 DoEvents
解决这个问题 with/without 吗?
注意:我知道 VB6 并不真正支持多线程,对于这种情况可能是一个 PITA。我实际上正计划升级软件并使用 .Net
重新创建它,但这需要一些时间。这就是为什么我需要在 VB6 中解决这个问题,因为现在该软件是用 VB6 编写的。
好吧,我设法弄清楚了问题,并且已经解决了。
简答
不要使用DoEvents
..有些数据不会传送?那么,仅在 SendComplete
事件中关闭连接。
长答案
第一件事:
为什么我首先使用 DoEvents
?因为某些 sent 邮件没有送达。网上很多articles/questions建议在Socket.SendData
之后使用DoEvents
,以保证数据到达接收方。
我对此进行了更深入的研究,试图找出邮件未送达的原因。我发现这个问题只有在发送消息后关闭连接时才会出现:
Socket.SendData "Message"
'
'
Socket.Close
所以,我只是将关闭连接的行移到 SendComplete
事件,删除了 DoEvents
句子 - 因为我不再需要它了 - 问题就消失了: )
Private Sub sckAccept_SendComplete(Index As Integer)
sckAccept_Close (Index)
End Sub
希望对遇到同样问题的人有所帮助。