AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Timer in TThread

Ein Thema von luke2 · begonnen am 26. Sep 2012 · letzter Beitrag vom 26. Sep 2012
Antwort Antwort
luke2

Registriert seit: 17. Jun 2009
117 Beiträge
 
#1

Timer in TThread

  Alt 26. Sep 2012, 03:13
Delphi-Version: XE2
Hi!

Ich habe einen TThread, der mit einem blockierendem Socket auf Daten wartet:
Delphi-Quellcode:
procedure MeinThread.Execute;
var i: integer;
begin
  repeat
    i := recv(sock, ...); //block
    if i > 0 then
    begin
      ...
    end;
  until i <= 0;
end;
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.
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?

Geändert von luke2 (26. Sep 2012 um 03:16 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#2

AW: Timer in TThread

  Alt 26. Sep 2012, 06:14
Du könntest einen zweiten Thread laufen lassen, in dem dann parallel gesendet wird. Ist so ziemlich die einzige Möglichkeit schätze ich.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie
(Moderator)

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#3

AW: Timer in TThread

  Alt 26. Sep 2012, 09:08
Verabschiede dich mal von den fünf Sekunden. Windows ist kein Echtzeitbetriebssystem. Lege den Empfänger so aus, dass er ankommende Daten puffern kann.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.622 Beiträge
 
Delphi 2007 Enterprise
 
#4

AW: Timer in TThread

  Alt 26. Sep 2012, 09:38
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.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
37.228 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: Timer in TThread

  Alt 26. Sep 2012, 11:08
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.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014
  Mit Zitat antworten Zitat
luke2

Registriert seit: 17. Jun 2009
117 Beiträge
 
#6

AW: Timer in TThread

  Alt 26. Sep 2012, 13:03
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?
  Mit Zitat antworten Zitat
Benutzerbild von Mavarik
Mavarik

Registriert seit: 9. Feb 2006
Ort: Stolberg (Rhld)
3.973 Beiträge
 
Delphi 10.3 Rio
 
#7

AW: Timer in TThread

  Alt 26. Sep 2012, 13:48
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
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#8

AW: Timer in TThread

  Alt 26. Sep 2012, 14:00
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:
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;
Und ansonsten:
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.
Andreas
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:50 Uhr.
Powered by vBulletin® Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf