幾年前,我做了一個軟件,使用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