2016-05-31 7 views
2

Ich machte ein Software-Paar vor Jahren mit VB6, die als TCP-Server funktioniert, empfängt mehrere Verbindungen von Clients.VB6 Winsock mehrere TCP-Verbindungen> Probleme mit DoEvents

Die Grundidee der Software ist auf einen bestimmten Port zu hören, Verbindungen von verschiedenen Clients zu akzeptieren und jede Verbindung zu einem separaten Winsock, der die Daten analysiert, sieht in DB, antwortet mit der richtigen Nachricht und dann schließt die Verbindung.

Hier einige Code:

Initialisieren der Buchsen, wenn die Anwendung gestartet wird:

For i = 1 To MaxCon  
    Load sckAccept(i) 
Next i 
sckListen.Listen 

annehmen Verbindungen:

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 

Empfangen von Daten, es zu analysieren und beantworten :

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 

Alles funktioniert gut, aber jetzt ist die Anzahl von Verbindungen (Paar Dutzende pro Sekunde) erhöht, so dass die Software gestartet Out of stack space Ausnahme bekommen (wegen DoEvents).

Ich weiß, dass in vielen Fällen DoEvents ist böse, aber wenn ich es entfernen, wird die Benutzeroberfläche der Anwendung nicht reagieren (wegen der Überlastung des Threads) und einige Daten möglicherweise nicht geliefert werden.

Also, meine Frage ist: hat jemand eine Idee, wie man dieses Problem mit/ohne DoEvents umgehen?


Hinweis: Ich weiß, dass VB6 wirklich Multi-Threading nicht unterstützt und könnte eine PITA für solche Situationen. Ich plane eigentlich, die Software zu aktualisieren und es mit .Net neu zu erstellen, aber das wird einige Zeit dauern. Deshalb muss ich dieses Problem in VB6 beheben, da die Software vorerst in VB6 geschrieben ist.

+0

Ich verstehe ehrlich nicht, warum die Ereignisse in der letzten Zeile des Dataarrival-Handler sein sollten, hätte ich es in die schwere Schleife gelegt. Technisch gesehen macht die doevents einen einfachen "yield", also kann der out of stack Fehler eine andere Quelle wie die sdata haben, ich würde ihn in ein Array außerhalb platzieren und mit dem Verbindungsindex darauf zugreifen, ich verstehe vollkommen das ist dreckig, aber sollte helfen, einige Haufen zu retten. – Gar

+0

1- Ich habe "DoEvents" in den 'DataArrival' -Handler geschrieben, weil es' Winsock.SendData' auslöst und "wenn ich es entferne, wird die Benutzeroberfläche der Anwendung nicht (wegen der Überlastung des Threads) und einiger Daten antworten nicht geliefert werden ". 2- Was meinst du mit 'Schwerlast'? 3- Wenn der Fehler 'Out of stack space' auftritt, ist der Stack voll von 'sckAccept_DataArrival' Events. Ich nehme an, dies ist, weil "DoEvents" das Ereignis erneut ausgelöst werden kann (das enthält andere 'DoEvents' usw.). 4- Die 'sData' Größe ist ziemlich klein (40-100 Byte) –

+0

ich verstehe ganz genau, warum du die Doevents benutzt hast, ich sehe es einfach nicht am Ende des Subs, ich verwende" doevents "innerhalb von Loops, so dass der Schleife sperren Sie die Anwendung nicht. Und selbst wenn die SData klein ist, kann man nur ein wenig Platz verdienen, indem man sie nach draußen legt und nichts loslässt. Ich verstehe auch, dass das, was Ihr Problem verursacht, eine Stapelung von unbeantworteten TCP-Abfragen ist (da ihr Handler die Datenbank nach ihnen abfragt). – Gar

Antwort

1

Nun, ich habe es geschafft, das Problem zu lösen, und habe es gelöst.

Die kurze Antwort

NICHT DoEvents Verwenden Sie .. werden einige Daten nicht übermittelt werden? Schließen Sie die Verbindung NUR im SendComplete Ereignis.


Die lange Antwort

Das erste, was zuerst:

Warum habe ich DoEvents in erster Linie? weil einige der gesendet Nachrichten wurden nicht geliefert. Viele Artikel/Fragen im Internet empfehlen, DoEvents nach Socket.SendData zu verwenden, um das Eintreffen der Daten beim Empfänger zu garantieren.

Ich graben tiefer in diese versuchen herauszufinden, warum die Nachrichten nicht geliefert werden. Ich fand heraus, dass dieses Problem nur auftritt, wenn die Verbindung nach dem Senden der Nachricht endet:

Socket.SendData "Message" 
' 
' 
Socket.Close 

So zog ich einfach die Zeile, die die Verbindung zum SendComplete Ereignisse schließt, entfernt, um den DoEvents Satz -Da ich nicht tun brauchen sie anymore-, und das Problem ist weg :)

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

ich hoffe, das jemand helfen könnte, die das gleiche Problem hat.