2

几年前,我使用 VB6 制作了一个软件,它用作 TCP 服务器,接收来自客户端的多个连接。

该软件的基本思想是侦听特定端口,接受来自不同客户端的连接,并将每个连接传递给单独的 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 编写的。

4

1 回答 1

2

好吧,我设法找出问题所在,并解决了它。

简短的回答

不要使用DoEvents.. 某些数据不会被传递?好吧,仅在SendComplete事件中关闭连接。


长答案

第一件事:

为什么我DoEvents首先使用?因为一些发送的消息没有被传递。互联网上的许多文章/问题建议使用DoEventsafterSocket.SendData以保证数据到达接收器。

我对此进行了更深入的研究,试图弄清楚为什么没有传递消息。我发现这个问题只有在发送消息后关闭连接时才会出现:

Socket.SendData "Message"
'
'
Socket.Close

所以,我只是移动了关闭与SendComplete事件的连接的行,删除了这DoEvents句话——因为我不再需要它了——问题就消失了:)

Private Sub sckAccept_SendComplete(Index As Integer)
    sckAccept_Close (Index)
End Sub

我希望这可以帮助有同样问题的人。

于 2016-06-08T16:17:40.257 回答