Entwickler-Ecke
Internet / Netzwerk - TimeOut für Datenempfang
HERB - Do 16.07.09 13:41
Titel: TimeOut für Datenempfang
Hallo
Ich habe einen SocketServer, der von einem SocketClient Daten empfangen kann. Dies klappt auch wunderbar, allerdings möchte ich nun einen Timeout einbauen.
Durch den Timeout soll der Datenempfang nur 3 Sekunden möglich sein. Falls in dieser Zeit keine Daten oder nicht alle Zeichen empfangen werden, soll das Empfangen abgebrochen werden.
Hier meine procedure Empfangen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| procedure Empfangen(var Was: String); var iBuf : Byte; Buffer : array[0..256] of Char; iTemp : Integer; begin Socket.ReceiveBuf(iBuf, 1); if Socket.ReceiveBuf(Buffer, iBuf) <> iBuf then begin RAISE Exception.Create('Fehler'); end; SetLength(Was, iBuf); move(Buffer, Was[1], iBuf); end; |
Niko S. - Do 16.07.09 14:30
Mein vorschlag wäre zu jedem "Clienten" eine zeit einzufügen in der das Paket angekommen ist ...
Und wenn das nächste Paket kommt wird das alte Paket gelöscht und das neue nicht als altes Paket behandelt sondern
als komplett neues.
Und wenn man jetzt sag ich mal prüfen will ob der nun nen DC hatte, dann kann man ja nen Timer im Hintergrund laufen lassen.
Narses - Do 16.07.09 14:49
Moin und :welcome: im Forum!
HERB hat folgendes geschrieben : |
| Durch den Timeout soll der Datenempfang nur 3 Sekunden möglich sein. Falls in dieser Zeit keine Daten oder nicht alle Zeichen empfangen werden, soll das Empfangen abgebrochen werden. |
Kannst du mal näher erläutern, was das für einen Sinn hat? :gruebel: Einfacher Ansatz: Timer starten, im OnTimer den Socket deaktivieren. :nixweiss: Das wird aber möglicherweise "interessante" Effekte bringen und einen gerade laufenden Empfang auch nicht abbrechen... (das ist auch bei der WSA im non-blocking-mode nicht so einfach möglich) :?
HERB hat folgendes geschrieben : |
| Hier meine procedure Empfangen: |
Wo und wann wird sie denn aufgerufen?
HERB hat folgendes geschrieben : |
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7:
| procedure Empfangen(var Was: String); var iBuf : Byte; Buffer : array[0..256] of Char; iTemp : Integer; begin Socket.ReceiveBuf(iBuf, 1); | |
Woher weißt du, dass jetzt ein Zeichen zum Lesen anliegt? Was machst du, wenn du keines lesen konntest?
HERB hat folgendes geschrieben : |
Delphi-Quelltext 1: 2:
| if Socket.ReceiveBuf(Buffer, iBuf) <> iBuf then begin | |
Wer sagt, dass hier ein komplettes Paket angekommen ist oder immer ankommen konnte? Sind deine Pakete immer max. 256 Bytes groß? Selbst dann kannst du nicht davon ausgehen, dass ein SendBuf auch "alles" bei einem ReceiveBuf abliefert. :idea: Das hier halte ich für eine potentielle Konzept-Fehlerstelle!
HERB hat folgendes geschrieben : |
Delphi-Quelltext 1: 2: 3: 4: 5:
| RAISE Exception.Create('Fehler'); end; SetLength(Was, iBuf); move(Buffer, Was[1], iBuf); end; | |
Der lokale Buffer ist unnötig. Du kannst auch direkt in den String schreiben. ;)
cu
Narses
HERB - Do 16.07.09 15:16
Narses hat folgendes geschrieben : |
| Moin und :welcome: im Forum! |
Danke!
Die procedure "Empfangen" wird im "ServerSocket1ClientRead" aufgerufen, so hier:
Delphi-Quelltext
1: 2: 3: 4:
| laenge := Socket.ReceiveLength; if laenge > 0 then begin try Empfangen(NawasEbenKommt); |
Aber wie kann ich dann mit einem Timer absichern, dass ich bekomme was ich bekommen soll.
Brauche ich das überhaupt?
Narses - Do 16.07.09 16:40
Moin!
HERB hat folgendes geschrieben : |
Die procedure "Empfangen" wird im "ServerSocket1ClientRead" aufgerufen, so hier:
Delphi-Quelltext 1: 2: 3: 4:
| laenge := Socket.ReceiveLength; if laenge > 0 then begin try Empfangen(NawasEbenKommt); | |
.ReceiveLength liefert nicht zwangsweise die exakte Ansatz Bytes im Empfangsbuffer des Sockets (ich empfehle hier mal die API-Doku). Wenn das Ereignis eintritt, einfach Lesen und schauen, was der Functionsaufruf abliefert. :nixweiss:
HERB hat folgendes geschrieben : |
| Aber wie kann ich dann mit einem Timer absichern, dass ich bekomme was ich bekommen soll. |
Also mit einem Timer alleine und deinen Konzept-Bröckelchen gar nicht.
HERB hat folgendes geschrieben : |
| Brauche ich das überhaupt? |
Woher soll ich das wissen? Nochmal:
Narses hat folgendes geschrieben : |
| Kannst du mal näher erläutern, was das für einen Sinn hat? :gruebel: |
cu
Narses
HERB - Do 16.07.09 16:55
Also, erstmal danke, dass Du so schnell antwortest!
Nun zum Problem:
Ich habe eine Anwendung, die einen SocketServer hat. Dieser SocketServer erhält Daten von einem Client (3 verschiedene Parameter).
Wenn ich alle 3 Parameter über meine procedure "Empfangen" erhalten habe, rufe ich eine URL auf (3.Parameter).
Nun will ich aber Timeouts einbauen, damit falls ein Client das Senden mittendrin abbricht, dass ich dies abfangen kann, und den User darüber informieren kann.
Danach soll der Server wieder bereit sein zum Empfang.
Narses - Do 16.07.09 17:09
Moin!
HERB hat folgendes geschrieben : |
Ich habe eine Anwendung, die einen SocketServer hat. Dieser SocketServer erhält Daten von einem Client (3 verschiedene Parameter).
Wenn ich alle 3 Parameter über meine procedure "Empfangen" erhalten habe, rufe ich eine URL auf (3.Parameter).
Nun will ich aber Timeouts einbauen, damit falls ein Client das Senden mittendrin abbricht, dass ich dies abfangen kann, und den User darüber informieren kann. |
Bei einer TCP-Verbindung rechnest du mit einem verdeckten Abbruch bzw. einen unvollständigen Sendevorgang? :shock: Was machst du da bloß... :gruebel:
HERB hat folgendes geschrieben : |
| Danach soll der Server wieder bereit sein zum Empfang. |
Ich habe den leisen Verdacht, du hast keine Ahnung, wie die Socket-API(WSA) bzw. TCP konzipiert ist, kann das sein? :?
Ich denke, du solltest dir mal
dieses Tutorial ansehen [
http://www.delphi-library.de/topic_TerminatorzeichenProtokollTutorial++1+Sockets+v400_54269.html], das hilft sicher weiter. :les: :think: ;)
cu
Narses
HERB - Fr 17.07.09 13:22
Tja dann sage ich mal entschuldigung für meine Unwissenheit.
Jedoch schicke ich so wie ich empfange, was die Sache bestimmt nicht besser macht, aber mit dem Code oben klappt es bisher immer.
Gut ich habe noch nen Sleep eingebaut hier->
Delphi-Quelltext
1: 2: 3:
| begin Sleep(500) Socket.ReceiveBuf(iBuf, 1); |
Selbst wenn ich von mehreren Clients Daten schicke, kommt das an, was ankommen soll.
Die Sache mit dem Timeout lasse ich nun einfach.
Narses - Fr 17.07.09 13:30
Moin!
HERB hat folgendes geschrieben : |
| Tja dann sage ich mal entschuldigung für meine Unwissenheit. |
Kein Grund zur Entschuldigung :nixweiss: sondern zum Nachholen. :zustimm:
HERB hat folgendes geschrieben : |
| Jedoch schicke ich so wie ich empfange, was die Sache bestimmt nicht besser macht, aber mit dem Code oben klappt es bisher immer. |
Empirischer Programmierstil ("funktioniert-doch-Code") ist kein Ersatz für ein vernünftiges Konzept (hier: Protokoll), das sollte klar sein. :?
HERB hat folgendes geschrieben : |
Gut ich habe noch nen Sleep eingebaut hier->
Delphi-Quelltext 1: 2: 3:
| begin Sleep(500) Socket.ReceiveBuf(iBuf, 1); |
Selbst wenn ich von mehreren Clients Daten schicke, kommt das an, was ankommen soll. |
Das ist keine Lösung, geschweige denn verdient es kaum den Namen "Workaround". Wenn du es sauber machen willst, nimm ein Protokoll mit entsprechend konzipierten Sende/Empfangsmethoden. Damit ist sowas wie dein "Sleep"-Ansatz schlicht überflüssig. ;)
HERB hat folgendes geschrieben : |
| Die Sache mit dem Timeout lasse ich nun einfach. |
Ja, würde ich auch vorschlagen.
cu
Narses
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!