![]() |
Delphi-Version: XE2
Timer in TThread
Hi!
Ich habe einen TThread, der mit einem blockierendem Socket auf Daten wartet:
Delphi-Quellcode:
Jetzt möchte ich z.B. alle 5 Sekunden etwas durch den Socket senden. Ich habe gelesen, dass es mit SetTimer gehen könnte, aber dafür wird eine Nachrichtenschleife benötigt und diese kann ja nicht immer ablaufen, da der Aufruf von recv blockiert, wenn keine Daten empfangen werden.
procedure MeinThread.Execute;
var i: integer; begin repeat i := recv(sock, ...); //block if i > 0 then begin ... end; until i <= 0; end; Schleife + Sleep funktioniert deshalb ja auch nicht... Was gibt es sonst noch für Möglichkeiten, ohne einen weiteren Thread zu starten bzw. auf nicht-blockierende Sockets umzustellen? |
AW: Timer in TThread
Du könntest einen zweiten Thread laufen lassen, in dem dann parallel gesendet wird. Ist so ziemlich die einzige Möglichkeit schätze ich.
|
AW: Timer in TThread
Verabschiede dich mal von den fünf Sekunden. Windows ist kein Echtzeitbetriebssystem. Lege den Empfänger so aus, dass er ankommende Daten puffern kann.
|
AW: Timer in TThread
Ich würde mich eher von blocking Sockets verabschieden, und statt dessen einen Empfangspuffer nehmen, und dann auf Trigger-Sequenzen im Thread reagieren. Dann kann der Thread nebenbei problemlos noch Sende-Aufgaben machen.
|
AW: Timer in TThread
Beim Senden über einen zweiten Thread muß man aber auch aufpassen, also ob die Connection multithreadet ist und ob man da gleichzeitig über unterschiedliche Threads senden und empfangen kann.
|
AW: Timer in TThread
Danke, ist es denn erlaubt auf dem gleichen Socket gleichzeitig recv und send (in 2 Threads) aufzurufen oder kann das zu unerwarteten Fehlern führen? Muss es synchronisiert werden?
|
AW: Timer in TThread
Eingangspuffer und non Blocking... Ist sicherlich der bessere Weg...
Kannst dann auf den event warten und mit 5 sekunden timeout dann deinen neuen Request senden... Mavarik |
AW: Timer in TThread
Also ich würde auf keinen Fall zwei Threads für einen Socket verwenden; das macht alles nur noch komplizierter.
Wenn du die recv()-Funktion aufruft; den Buffer aber als nil übergibst, dann solltest du entweder 0 oder die Anzahl der Bytes im Empfangspuffer oder einen Fehlercode erhalten.
Delphi-Quellcode:
Und ansonsten:
procedure MeinThread.Execute;
var i: integer; begin repeat i := recv(sock, Pointer(nil)^, -1); if i > 0 then begin i := recv(sock, buffer, sizeof(buffer)); ... end; Sleep(0); // Rechenzeit abgeben, andernfalls 100% CPU until i <= 0; end; Das direkte Benützen der WinSock API ist ziemlich kompliziert. Die API ist viel mächtiger als das was ein Anwendungsprogrammierer braucht. Also braucht man im Grunde genommen eine vereinfachte API für TCP/IP. Dieses Problem wurde schon zig-fach gelöst. Aber solange es Programmierer gibt sind sie dazu verdammt die gleichen Aufgaben immer wieder neu zu lösen. Empfehlenswert ist die Unit $Delphi\Source\VCL\ScktComp. Die Komponenten müssen nicht installiert werden. Man kann damit zwar nur TCP/IPv4 betreiben, aber der Code ist relativ schlank und durch die Events OnRead, OnConnect usw. ist die Verwendung ziemlich einfach. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:49 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz