Exception abfangen
-
ich erhalte in meinem Programm nach kurzer Zeit eine ESocketError-Exception. Ich verwende eine Socketverbindung über die Koponente TClientSocket zu einem Messgerät. Da dieses die Verbindung nach jeder Abfrage über "socket->Socket->ReceiveBuf(...);" trennt muss ich die Verbindung immer wieder mit "socket->Active = true;" aufbauen. Das ganze geschieht über einen Timer. Das Gerät habe ich gerade nicht zur Verfügung deshalb tritt der Fehler auf. Ich vermute ihn auch in dem Timer, deshalb habe ich ein try catch Zweig verwendet. Der Fehler tritt trotzdem noch auf.
Hier mal der Codeausschnitt:void __fastcall TfrmHO::timMesswerteAnzeigenTimer(TObject *Sender) { AnsiString status; try { socket->Active = true; socket->Socket->SendBuf(send, 32); Sleep(100); socket->Socket->ReceiveBuf(rec, 128); ch4 = ((rec[22]<<8) + rec[23])/10.0; co2 = ((rec[20]<<8) + rec[21])/100.0; o2 = ((rec[16]<<8) + rec[17])/10.0; h2 = ((rec[40]<<8) + rec[41]); h2s = ((rec[18]<<8) + rec[19]); if (rec[1]==0x01) status = "Ansaugen"; else if (rec[1]==0x02) status = "Messen"; else if (rec[1]==0x04) status = "Filtertest"; else if (rec[1]==0x08) status = "Spülen"; else if (rec[1]==0x10) status = "Kondensatentfernung"; else if (rec[1]==0x20) status = "Leeren"; else if (rec[1]==0x40) status = "anderer Programmschritt"; else if (rec[1]==0x80) status = "Kalibrierung"; else status = "STOP"; txtAnzeigeAwiStatus->Text = status; } catch(...) { Application->MessageBox("kann nicht mit Awi verbinden", "Verbindungsfehler", MB_OK); ch4 = co2 = o2 = h2 = h2s = 0; status = "Status: OFF"; }
In den Catch-Block scheint er gar nicht zu gehen, da ja meine MessageBox nicht angezeigt wird.
Kann ich denn irgendwo nachvollziehen wo soche Exceptions genau herkommen?
-
Welche Komponente? TClientSocket? Da gibt es ein Ereignis OnError, das mußt du in diesem Fall nutzen. Fehler werden damit innerhalb der Komponente abgefangen, somit kann ein try-catch-Block nicht greifen.
-
ok, hab jetzt die Fehlerbehandlung in das Event geschrieben. Da ergibt sich allerdings auch das Problem, dass der Fehler immer wieder angezeigt wird, da ja über einen Timer connected wird. Da dieser alle 1sek sich die Werte von dem Gerät holt wird natürlich auch alle 1sek der Fehler angezeigt.
void __fastcall TfrmHO::socketError(TObject *Sender, TCustomWinSocket *Socket, TErrorEvent ErrorEvent, int &ErrorCode) { Application->MessageBox("kann nicht mit Awi verbinden", "Verbindungsfehler", MB_OK); ch4 = co2 = o2 = h2 = h2s = 0; txtAnzeigeAwiStatus->Text = "Status: OFF"; }
den Code hab ich jetzt im ConnectEreignis stehen und im Timer verbinde über "socket->Active = true;"
Eine Fehlermeldung, dass ein SocketError aufgetren ist kommt trotzdem noch nach kurzer Zeit. Wie kann ich das unterbinden?
-
Hallo,
wo wird denn die Verbindung getrennt?
Vielleicht hilft das schon weiter:while (socket->active) {return;} socket->active = true;
oder
if (socket->active) socket->active = false; socket->active = true;
VlG
-
die Verbindung wird durch das Gerät nach jedem Aufruf von socket->Socket->ReceiveBuf(rec, 128); wiede3r getrennt
-
Hallo,
das würde ja bedeuten, dass der socket in einen Timeout rennt?
Was besagt denn der ESocketError? Timeout? Connection refused?
Hast du die geposteten BEispiele mal ausprobiert? Ich vermute dass socket noch geöffnet ist und es dann irgendwann zum "Überlauf" kommt.VlG
-
direkt mit dem Gerät probieren kann ich das leider im Moment nicht da ich das Gerät nicht mehr habe. Die Fehlermeldung lautet:
"Im Projekt Projekt1.exe ist eine Exception der Klasse ESocketError aufgetreten. Meldung: "Asynchroner Socket-Fehler 10060. Prozess anhalten. Mit EInzelne ANweisung oder Start fortsetzen." Die Meldung kommt erst während der Laufzeit nach ca. 15 Sekunden.Starte ich die Projekt1.exe direkt, kommt nur die Fehlermeldung: "Asynchroner Socket-Fehler 10060".
-
Hallo,
10060 ist Timeout! Die Verbindung wird zwar vom gerät getrennt, dass heißt aber noch lange nicht, dass der socket die verbindung ebenfalls zu macht. Versuch es vor jeder neuen Verbindung mit socket->active = false;
VlG
-
habs grad mal mit
if (socket->Active) socket->Active = false; socket->Active = true;
probiert. Diese Anweisungen stehen im Timerevent und werden alle 1 sek aufgerufen.
Der Fehler tritt trotzdem noch auf. Das Gerät ist aber wie gesagt auch nicht verbunden. Aber der Fehler sollte natürlich nicht auftreten, da das Gerät ja auch mal getrennt werden soll ohne dass mein Programm abstürzt.
-
Manchmal lohnt es sich in die BCB-Hilfe zu schauen:
Das Ereignis OnError tritt ein, wenn der Socket eine Verbindung nicht herstellen, benutzen oder schließen kann.
__property TSocketErrorEvent OnError = {read=FOnError, write=FOnError};
Beschreibung
In einer Behandlungsroutine für OnError können Sie auf Fehler reagieren, die in Zusammenhang mit einer Socket-Verbindung auftreten. Wenn die Ereignisbehandlungsroutine für OnError die Fehlerbedingung erfolgreich behandeln konnte, setzen Sie den Parameter ErrorCode auf 0, damit keine ESocketError-Exception ausgelöst wird.
-
Hallo,
das sorgt aber lediglich dafür dass die Meldung nicht mehr angezeigt wird. Der Fehler ist dadurch nicht behoben! Der Timeout muss ja eine Ursache haben.
VlG
-
rudpower schrieb:
Der Fehler tritt trotzdem noch auf. Das Gerät ist aber wie gesagt auch nicht verbunden. Aber der Fehler sollte natürlich nicht auftreten, da das Gerät ja auch mal getrennt werden soll ohne dass mein Programm abstürzt.
Hab ich so interpretiert, als könne da zur Zeit nur ein Timeout rauskommen.