Entwickler-Ecke

Internet / Netzwerk - [UDP] Nachricht an alle Teilnehmer senden (Zeitverzögerung)


Delete - Di 06.03.07 12:29
Titel: [UDP] Nachricht an alle Teilnehmer senden (Zeitverzögerung)
Hi,

Ich verwende die UDPSockUtil Komponente, die hier im Forum bereitgestellt wurde (an dieser Stelle nochmal ein Lob für die tolle Komponente). Nun zu meiner Frage:
Ich will bei Button1Click eine Info an alle Teilnehmer schicken, deren IP-Adressen in der ListView1 stehen. Bisher geht das zwar, aber es dauert ca. 5 Sekunden, ehe das Programm wieder reagiert. Die Funktion sieht so aus:


Delphi-Quelltext
1:
2:
3:
4:
5:
for User := 0 to frmMain.ListView1.Items.Count - 1 do 
begin 
UDPSockUtil1.RemoteHost := frmMain.ListView1.Items[User].SubItems[1]; 
UDPSockUtil1.SendText(Username + '#' + IntToStr(User)); 
end;


Ich denke ich weiss, wie es in der Theorie funktioniert - nämlich mit Threads - aber in der Thematik kenne ich mich nicht wirklich so gut aus. Könnte mir das vielleicht jemand anhand meinem aktuellen Problem erklären? Wäre echt nett!

Danke schonmal!

Gruß Christian

Moderiert von user profile iconmatze: Code- durch Delphi-Tags ersetzt


JayEff - Di 06.03.07 14:44

Wenn du willst, dass das Programm weiter reagiert, während deine Nachricht gesendet wird, füge in die Schleife ein Application.ProcessMessages; ein. Dann könntest du noch eine Progressbar einfügen, mit der du den Fortschritt anzeigst, so dass der User nicht denkt, nach dem Klick wäre bereits alles erledigt.


Narses - Di 06.03.07 15:07

Moin!

Der Hinweis von user profile iconJayEff ist schon ganz gut. ;)

Ich denke, die Verzögerung kommt durch eine Hostnamenauflösung zustande (du hast eine Wählverbindung/DSL, richtig?). Wenn du die IP als Adresse verwendest, kannst du so auch nochmal Zeit "einsparen" (zumindest, wenn du die IP hast :?).

Ansonsten hilft die Idee mit dem Thread natürlich weiter, aber da die VCL nicht threadsave ist, sind so Ansätze (Liste in VCL-Kompo) immer nicht ganz leicht (und nicht in "drei Worten/Codeschnipseln") zu erklären. user profile iconLuckie hat auf seiner HP ein gutes Thread-Tutorial, vielleicht solltest du da mal reinsehen. ;)

cu
Narses


Delete - Di 06.03.07 18:02

user profile iconNarses hat folgendes geschrieben:
Moin!

Der Hinweis von user profile iconJayEff ist schon ganz gut. ;)


Ja, hat mir auch schon ein wenig geholfen, danke!

Das eigentliche Problem ist aber immer noch da und das könnte an dem Grund liegen, den du angeführt hast:

user profile iconNarses hat folgendes geschrieben:
Ich denke, die Verzögerung kommt durch eine Hostnamenauflösung zustande (du hast eine Wählverbindung/DSL, richtig?). Wenn du die IP als Adresse verwendest, kannst du so auch nochmal Zeit "einsparen" (zumindest, wenn du die IP hast :?).

Ansonsten hilft die Idee mit dem Thread natürlich weiter, aber da die VCL nicht threadsave ist, sind so Ansätze (Liste in VCL-Kompo) immer nicht ganz leicht (und nicht in "drei Worten/Codeschnipseln") zu erklären. user profile iconLuckie hat auf seiner HP ein gutes Thread-Tutorial, vielleicht solltest du da mal reinsehen. ;)


Also vorneweg: das Tutorial von Luckie kenne ich bereits. Ich finde es aber leider nicht so verständlich, wie ich es mir wünschen würde. Ich lerne besser anhand von Beispielen. Die Beispiele von Luckie sind aber nicht so recht solche, die mir weiterhelfen. Ich stand schon öfters vor dem jetzigen Problem. Ich bin es irgendwie immer umgangen, aber dieses Mal geht´s eben nicht :-(
Kann es sein, dass es mehrere Arten von Threads gibt?


Narses - Di 06.03.07 18:31

Moin!

user profile iconYheeky hat folgendes geschrieben:
Kann es sein, dass es mehrere Arten von Threads gibt?

Hm, AFAIK nicht. Thread ist Thread. ;) Es gibt allerdings Dinge zu beachten, je nachdem, in welchem Thread-Kontext dein Code läuft (z.B. darfst du aus einem anderen als dem Hauptthread (=VCL-Thread) nicht auf die VCL zugreifen, eben nur synchronisiert).

user profile iconYheeky hat folgendes geschrieben:
Also vorneweg: das Tutorial von Luckie kenne ich bereits. Ich finde es aber leider nicht so verständlich, wie ich es mir wünschen würde.

Also ich will ehrlich sein, wenn du beim Thema Threads noch nicht soo firm bist, dann ist es sicher keine gute Idee, gleich mehrere Probleme auf einmal anzugehen (VCL-Zugriff, Synchronisation, Kommunikation). :?

Mein Vorschlag: mach doch erstmal ein paar (andere?) Tuts zum Thema Threads, versuch dich an ein paar kleineren Beispielen (aus Threads synchronisiert auf die VCL zugreifen, Datenaustausch mit Threads, etc.) und geh dann erst nochmal auf dein aktuelles Problem zu. So einfach sich dein Vorhaben auch anhören mag, letztlich ist es das leider nicht... :|

cu
Narses


Delete - Di 06.03.07 18:57

Okay...wie du meinst. Ich hätte dir nicht mal sagen können, dass ich gleich 3 Probleme auf einmal hab ;-)
Kennst du vielleicht Tuts die für Anfänger geeignet sind?


Narses - Di 06.03.07 20:33

Moin!

Schonmal in unsere Library [http://www.delphi-library.de] geschaut? Wenn da nix weiter für dich bei ist (ich verweise sonst auch immer nur auf user profile iconLuckies Tut), dann habe ich auch leider sonst nix bei der Hand. :?

cu
Narses


Robinator - Di 06.03.07 20:45


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
TUDPThread = class(TTHread)
  private
    FRemoteHost : String;
    FText : String;
  protected
    procedure Execute; override;
  public
    Constuctor Create(ARemoteHost, AText : String);

constructor TUDPThread.Create(ARemoteHost, AText : String);
begin
  inherited Create(True);
  FRemoteHost := ARemoteHost;
  FText := AText;
  Suspended := false;
end;

procedure TUDPThread.Execute;
begin
  UDPSockUtil1.RemoteHost := FRemoteHost; 
  UDPSockUtil1.SendText(FText); 
end;


Ungetesten und nur so hier reingetipselt, aber als Ansatz sollte es dennoch helfen ;)

gruss, rob


Narses - Mi 07.03.07 00:07

Moin!

user profile iconRobinator hat folgendes geschrieben:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
TUDPThread = class(TTHread)
  private
    FRemoteHost : String;
    FText : String;
  protected
    procedure Execute; override;
  public
    Constuctor Create(ARemoteHost, AText : String);

constructor TUDPThread.Create(ARemoteHost, AText : String);
begin
  inherited Create(True);
  FRemoteHost := ARemoteHost;
  FText := AText;
  Suspended := false;
end;

procedure TUDPThread.Execute;
begin
  UDPSockUtil1.RemoteHost := FRemoteHost; 
  UDPSockUtil1.SendText(FText); 
end;

Sorry, aber ich rate dringend davon ab, den Code so zu verwenden! :shock: :mahn:

Die Execute-Methode muss mindestens in eine CriticalSection, noch besser, einen dynamischen UDP-Socket im Thread erzeugen und nach dem Senden freigeben, um kein Chaos mit den Ereignissen zu bekommen (wenn man denn diese noch verwenden will)! Abgesehen davon würde die DNS-Auflösung ohne einen separaten UDP-Socket auch wieder nicht parallelisiert, was ja die "Zeitersparnis" bringen soll. :?

Bitte, das sieht einfacher aus, als es wirklich ist! :mahn:

cu
Narses


Delete - Mi 07.03.07 00:16

Also ich habe doch noch ein Tutorial gefunden. Dem werde ich mich morgen mal widmen.

@Robinator: Danke erstmal! Ich habe gerade mal deinen Code ausprobiert. Beim Aufruf bekomme ich jedoch eine Fehlermeldung:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
procedure UDPSendString;
var 
  Send_Thread : TUDPThread;
  TempRemoteHost, TempText : String;
begin
TempRemoteHost := frmMain.Users.Items[User].SubItems[4];
TempText := OwnComputername;

Send_Thread.Create(TempRemoteHost, TempText);

end;


Woran könnte das liegen?

Gruß Christian

Moderiert von user profile iconChristian S.: Code- durch Delphi-Tags ersetzt


Delete - Mi 07.03.07 00:18

Okay, habe jetzt erst leider deine Nachricht gelesen *g*...wenn´s so schwierig ist, wie soll ich das denn dann hinbekommen?! :cry:


Narses - Mi 07.03.07 00:24

Moin!

user profile iconYheeky hat folgendes geschrieben:
Okay, habe jetzt erst leider deine Nachricht gelesen *g*...wenn´s so schwierig ist, wie soll ich das denn dann hinbekommen?! :cry:

So: ;)
user profile iconYheeky hat folgendes geschrieben:
Also ich habe doch noch ein Tutorial gefunden. Dem werde ich mich morgen mal widmen.

Ich habe im Verlauf dieses Themas schon alle wichtigen Hinweise gegeben (ach ja, in user profile iconRobinators Code fehlt natürlich auch noch das Freigeben des Thread-Objekts...), einfach mit der Materie vertraut machen und probieren; es ist noch kein Meister vom Himmel gefallen... ;)

cu
Narses


Robinator - Mi 07.03.07 03:21

user profile iconNarses hat folgendes geschrieben:
Sorry, aber ich rate dringend davon ab, den Code so zu verwenden! :shock: :mahn:


Ich hab überhaupt nichts von so verwenden gesagt, ich sagte, dass es sich bei dem code um einen Ansatz handelt (wer lesen kann ist klar im Vorteil)


user profile iconNarses hat folgendes geschrieben:
Ich habe im Verlauf dieses Themas schon alle wichtigen Hinweise gegeben (ach ja, in Robinators Code fehlt natürlich auch noch das Freigeben des Thread-Objekts...)


Der Thread gibt sich selber frei sobald er mit dem Execute fertig ist. Critical sections benötigt man im TThread für derartige dinge eigentlich nicht :). Auch geht es nicht um Zeitersparniss, sondern um das Einfrieren des Programms.




gruss, rob


Narses - Mi 07.03.07 10:19

Moin!

user profile iconRobinator hat folgendes geschrieben:
Ich hab überhaupt nichts von so verwenden gesagt, ich sagte, dass es sich bei dem code um einen Ansatz handelt (wer lesen kann ist klar im Vorteil)

OK, dann so: "Ich rate drigend davon ab, den Ansatz weiter zu verfolgen!" :mahn: Jetzt besser? :P

user profile iconRobinator hat folgendes geschrieben:
Der Thread gibt sich selber frei sobald er mit dem Execute fertig ist.

Ist .FreeOnTerminate default True? :gruebel: mag sein, schadet aber nicht, dass trotzdem zu setzen, finde ich. ;)

user profile iconRobinator hat folgendes geschrieben:
Critical sections benötigt man im TThread für derartige dinge eigentlich nicht :).
:arrow:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
procedure TUDPThread.Execute;  
begin  
  UDPSockUtil1.RemoteHost := FRemoteHost;
  // hier kritische Stelle
  UDPSockUtil1.SendText(FText);   
end;

Da du offensichtlich mit einem globalen UDPSockUtil arbeiten willst (ich sehe jedenfalls keinen lokalen), kann dir von der DNS-Auflösung bis zum Senden ein anderer Thread dazwischen gehen (wenn du mehrere parallel startest, ist das sogar sehr wahrscheinlich) :shock: ->Chaos! :hair: -> CriticalSection. ;)

user profile iconRobinator hat folgendes geschrieben:
Auch geht es nicht um Zeitersparniss, sondern um das Einfrieren des Programms.

Das ist in diesem Fall ursächlich das gleiche (wer lesen kann ist klar im Vorteil)... ;)

cu
Narses


Robinator - Mi 07.03.07 13:05

Hallo Narses,

Irgendwie leuchtet mir nicht ein was du erreichen möchtest. Ich habe doch keine fertige Lösung gepostet, nichtmal behauptet, dass der Code komplett ist habe ich :(.


user profile iconNarses hat folgendes geschrieben:

Da du offensichtlich mit einem globalen UDPSockUtil arbeiten willst (ich sehe jedenfalls keinen lokalen), kann dir von der DNS-Auflösung bis zum Senden ein anderer Thread dazwischen gehen (wenn du mehrere parallel startest, ist das sogar sehr wahrscheinlich) :shock: ->Chaos! :hair: -> CriticalSection. ;)


NEIN! Ich möchte nicht mit einem globalen UDPSockUtil arbeiten, ich weis nichtmal was ein UDPSockUtil für eine Komponente ist. Alles was ich wollte ist, ein Beispiel geben, wie man mit Threads arbeitet!

Also, ersteinmal nichts für ungut. Ich finde allerdings, das dein Ton auch etwas freundlicher ausfallen könnte (meiner im letzten Post auch, das gebe ich zu :) ).

Gruss, rob


Narses - Mi 07.03.07 13:15

Moin!

user profile iconRobinator hat folgendes geschrieben:
Also, ersteinmal nichts für ungut. Ich finde allerdings, das dein Ton auch etwas freundlicher ausfallen könnte (meiner im letzten Post auch, das gebe ich zu :) ).

:? Ich finde meinen Ton zwar maximal warnend, aber wenn du dir auf den Schlips getreten vorkommst, war das definitiv nicht beabsichtigt! :shock: Also, sorry. ;)

user profile iconRobinator hat folgendes geschrieben:
Irgendwie leuchtet mir nicht ein was du erreichen möchtest. Ich habe doch keine fertige Lösung gepostet, nichtmal behauptet, dass der Code komplett ist habe ich :(.
[...]
Ich möchte nicht mit einem globalen UDPSockUtil arbeiten, ich weis nichtmal was ein UDPSockUtil für eine Komponente ist. Alles was ich wollte ist, ein Beispiel geben, wie man mit Threads arbeitet!

Ich möchte erreichen, dass du keine Beispiele/Ansätze gibst, die mit den verwendeten Komponenten nicht klappen werden. ;) Du hast Recht, für einen Thread alleine ist das Beispiel/der Ansatz OK, aber eben nicht, wenn Netzwerkkommunikation ins Spiel kommt! :idea: Darauf habe ich aber auch schon vorher hingewiesen. ;)

cu
Narses


Delete - Mi 07.03.07 13:49

Also soll ich mehrere UDPSockUtils verwenden oder wie meinst du das?


wulfskin - Mi 07.03.07 13:51

Hallo,

auf wenn Narses eigentlich schon darauf hingewiesen hat, möchte ich nochmal darauf zurückkommen: Die Verzögerung scheint ja durch die Hostauflösung zu kommen!

Deshalb könntest du ja auch einfach für jeden Hostnamen die IP-Adresse suchen und intern speichern. Damit braucht es zwar beim ersten Senden länger (außer du machst das schon davor), danach sollte es dann aber schneller gehen, womöglich so schnell, dass du gar keine Threads mehr brauchst!

Das ist dann nicht 100% professionel, aber du kannst trotzdem weiterarbeiten, warscheinlich mit einer vernünftigen Geschwindigkeit.

Viel Glück,
Hape


Robinator - Mi 07.03.07 13:51

Ja, pro Thread einen ;)


Delete - Mi 07.03.07 17:04

Okay, also sollte ich vielleicht erstmal versuchen die Hostauflösung in einen Thread zu machen oder? Dann sollte das mit dem Einfrieren schonmal weg sein.
Die allgemein schlechte Performance liegt dann also daran, dass alles über eine Komponente läuft, richtig?
Ich kann natürlich für jede Verbindung einen neuen UDPSockUtil anlegen, nur wird das Ereignis OnReceiver dann ja für jede Komponente abgefragt. Sorgt das dann nicht auch für eine Programmüberlastung?


Robinator - Mi 07.03.07 17:13

Versuch es doch mal so:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
TUDPThread = class(TTHread)
  private
    FRemoteHost : String;
    FText : String;
  protected
    procedure Execute; override;
  public
    Constuctor Create(ARemoteHost, AText : String);
end;

constructor TUDPThread.Create(ARemoteHost, AText : String);
begin
  inherited Create(True);
  FRemoteHost := ARemoteHost;
  FText := AText;
  FreeOnTerminate := True; //Zufrieden? :P
  Suspended := false;
end;

procedure TUDPThread.Execute;
begin
  with TUDPSockUtil.Create do //Ich gehe mal davon aus, dass die Komponente so heisst - wenn nicht hier den Namen einfügen
  try
    RemoteHost := FRemoteHost; 
    SendText(FText); 
  finally
    Free;
  end;
end;


//Aufruf dann so:

for User := 0 to frmMain.ListView1.Items.Count - 1 do 
  TUDPThread.Create(frmMain.ListView1.Items[User].SubItems[1], Username + '#' + IntToStr(User));


Das ist wieder nur ein Ansatz (ehe sich jemand beschwert :P ), könnte aber nach meinem Verständniss funktionieren :)

gruss, Rob


Delete - Mi 07.03.07 17:36

So, mein Programm sieht nun so aus:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
constructor TUDPThread.Create(VPort : Integer; VRemoteHost : String);
var UDPSockUtil : TUDPSockUtil;
begin
inherited Create(True);
  CLocalPort := VPort;
  CRemoteHost := VRemoteHost;

  // UDPSockUtil erstellen
  UDPSockUtil := TUDPSockUtil.Create(frmMain);
  UDPSockUtil.LocalPort:= VPort;
  UDPSockUtil.RemoteHost := VRemoteHost;
  Suspended := False;

end;


Der Aufruf ist wiefolgt (bei OnButtonClick):

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
for User := 0 to Users.Items.Count - 1 do
      begin
      Application.ProcessMessages;

      TUDPThread.Create(Port, Users.Items[User].SubItems[0]);
      end;


Trotzdem kann ich die Form nicht bewegen, wenn ich den Button drücke... :( wieso denn? Ich richte die Komponente ja bisher nur ein und Connecte nicht.

EDIT: Okay, auch wenn sich die Komponente nicht verbindet, versucht er schon beim Eintragen den Namen aufzulösen. Nichtsdestotrotz möchte ich den "Einfrieren" Effekt hierbei ja nicht haben...


Robinator - Mi 07.03.07 17:44

du erstellst UDPSockUtil in konstruktor als lokale Variable. Das hat erstens keinen SInn, weil du im Execute darauf nichtmehr zugreifen kannst und zweitens wird der Creator nicht Asynchron ausgeführt. Nimm das da mal raus und versuch es dann nochmal ;). Das UDPSockUtil wird ja im Execute eh schon erstellt.

gruss, rob


Delete - Mi 07.03.07 18:14

Ah, okay :oops:

Aber der Code...


Delphi-Quelltext
1:
2:
3:
4:
 // UDPSockUtil erstellen
  UDPSockUtil := TUDPSockUtil.Create(frmMain);
  UDPSockUtil.LocalPort:= VPort;
  UDPSockUtil.RemoteHost := VRemoteHost;


...wird doch dann ins Execute gestellt oder? Ansonsten weiss Execute ja garnicht, dass er ne Komponente vom Typen TUDPSockUtil erstellen soll...


Robinator - Mi 07.03.07 18:37

Wieso sollte das "ins execute gestellt" werden? Das leuchet mir jetzt irgendwie überhaupt nicht ein :)


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
procedure TUDPThread.Execute;
begin
  with TUDPSockUtil.Create do //Hier wird die komponente erstellt
  try
    RemoteHost := FRemoteHost; 
    SendText(FText); 
  finally
    Free;
  end;
end;


Delete - Mi 07.03.07 18:48

Okay, aber angenommen das würde nicht im Execute stehen...dann würde doch auch meine Variante funktionieren oder was spricht dagegen?


Robinator - Mi 07.03.07 18:51

Habn ich doch eben schon gesagt. Der Konstruktor wird nicht asynchron ausgeführt... da kannst du es genauso gut im Mainthread laufen lassen.


Delete - Mi 07.03.07 18:58

Okay vielleicht hab ich mich falsch ausgedrückt, deswegen nochmal auf die Gefahr hin mit zu wiederholen *g*.

Richtig?


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
procedure TUDPThread.Execute;
begin
  with TUDPSockUtil.Create do //Hier wird die komponente erstellt
  try
    RemoteHost := FRemoteHost; 
    SendText(FText); 
  finally
    Free;
  end;
end;


Falsch?


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
procedure TUDPThread.Execute;
var UDPSockUtil : TUDPSockUtil;
begin
  UDPSockUtil := TUDPSockUtil.Create(frmMain);
  UDPSockUtil.LocalPort:= VPort;
  UDPSockUtil.RemoteHost := VRemoteHost;
end;


Wenn dem so ist: wieso muss das dann mit TObject.Create und while...do...gemacht werden abgesehen davon, dass es dann nicht asynchron ausgeführt wird?


Robinator - Mi 07.03.07 19:51

Das is beides ansich das gleiche. Nur hast du kein SendText drinne und gibst das Objekt nicht wieder frei ;)

Zudem solltest du nicht frmMain als Owner übergeben

gruss, Rob

Ps.: wo siehst du da ein while..do und wo ein TObject?


Delete - Mi 07.03.07 19:58

Verlesen...meinte natürlich das with...do und mit TObject meinte ich die UDP Kompo...okay, dann danke erstmal. Ich schau mal wie weit ich komme, ehe ich mich hier wieder melden muss ;-)
Danke nochmal!

Gruß Christian


Narses - Mi 07.03.07 23:57

Moin!

Ich möchte nochmal auf die allgemeinen Fragen eingehen, das mit dem (Sende-)Thread hat dir user profile iconRobinator ja nun schon hingebogen: ;)
user profile iconYheeky hat folgendes geschrieben:
Okay, also sollte ich vielleicht erstmal versuchen die Hostauflösung in einen Thread zu machen oder? Dann sollte das mit dem Einfrieren schonmal weg sein.
Die allgemein schlechte Performance liegt dann also daran, dass alles über eine Komponente läuft, richtig?

Je länger ich so darüber nachdenke, desto mehr frage ich mich, WARUM die Hostnamensauflösung bei dir sooo lange dauern sollte, dass die einzelnen GetHostByName()-Calls derartige Blockaden bewirken... :gruebel: vor allem, weil nachfolgende Auflösungen aus dem lokalen DNS-Cache bedient werden. Ausser(!): es handelt sich um einen fehlerhaften Hostnamen oder du hast eine Fehlkonfiguration in deiner DNS-Anbindung... :?!?: das würde es erklären! :idea:

Der Ansatz mit den Sende-Threads ist zwar ein Workaround für das Problem, aber es geht eigentlich nicht auf die Ursache ein. Wenn alle Hosts, die du in deiner Liste hast, gültig sind, dann sollte die erste Auflösung vielleicht etwas dauern, aber alle folgenden nicht (wohlgemerkt, die erste Auflösung innerhalb von 24 Stunden(?) oder so! jedenfalls innerhalb der lokalen Cach-Dauer). Ich frage mich also ernsthaft, ob du nicht vielleicht ein anderes, grundlegendes Problem hast und jetzt nur daran "vorbeiprogrammierst"... :?:

user profile iconYheeky hat folgendes geschrieben:
Ich kann natürlich für jede Verbindung einen neuen UDPSockUtil anlegen, nur wird das Ereignis OnReceiver dann ja für jede Komponente abgefragt. Sorgt das dann nicht auch für eine Programmüberlastung?

Für den Empfang musst du natürlich weiterhin die statische IDE-Kompo auf dem Formular verwenden. ;) Aber du hast natürlich Recht mit der "Befürchtung", dass der Sende-Thread-Ansatz nicht gerade eine resourcensparende "Alternative" ist... :?

Deshalb: du solltest IMHO versuchen, die Ursache für die lange DNS-Auflösung zu finden; oder vielleicht ist es ja noch ganz was anderes... ? Fazit: Das mit dem Sende-Thread mag zwar "funktionieren", aber deshalb halte ich den Ansatz immer noch nicht für "sauber". :| :(

cu
Narses


Delete - Do 08.03.07 00:17

Also die Sache ist: bei mir zuhause hat das alles schon reibungslos funktioniert. In der Berufsschule habe ich es dann versucht und da ist das Programm eingefroren. Das Netzwerk ist ziemlich groß und so kam ich schon dazu, dass ich vom Broadcasting auf das direkte Senden umgestiegen bin.

Nochmal eine Frage:

Mit folgendem Code versuche ich eine Komponente zu erzeugen:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
constructor TUDPThread.Create(VRemoteHost : String; VIndex : Integer);
begin
inherited Create(True);
  CRemoteHost := VRemoteHost;
  CIndex := VIndex;
  FreeOnTerminate := True;
  Suspended := False;

end;

procedure TUDPThread.Execute;
begin
with TUDPSockUtil.Create(Application) do
  try
    Name := 'UDPClient' + IntToStr(CIndex);
    LocalPort := 3110;
    RemoteHost := CRemoteHost;
  finally
    Free;
  end;

end;


Dann habe ich 2 Buttons. Mit dem einen erstelle ich eine Komponente und mit dem anderen frage ich ab, ob es eine Komponente mit dem Namen gibt:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
procedure TForm10.Button1Click(Sender: TObject);
begin
if CompExists('UDPClient0') = True then
ShowMessage('Existiert')
 else
ShowMessage('Existiert nicht');

end;

procedure TForm10.Button2Click(Sender: TObject);
begin
TUDPThread.Create(''0);

end;


Hier dann noch die CompExists-Funktion:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
function CompExists(Componentname : String) : Boolean;
var Comp : SmallInt;
begin
Result := False;

for Comp := 0 to Application.ComponentCount-1 do
  if Application.Components[Comp] is TUDPSockUtil then
   if TUDPSockUtil(Application.Components[Comp]).Name = ComponentName then
   Result := True;

end;


Ich bekomme jedoch immer angezeigt, dass eine Komponente mit dem Namen nicht existiert :-(


Narses - Do 08.03.07 00:23

Moin!

Augenblick mal (den Rest des Beitrags habe ich mir noch nicht genau angesehen, kommt noch); du willst damit sagen:
user profile iconYheeky hat folgendes geschrieben:
Also die Sache ist: bei mir zuhause hat das alles schon reibungslos funktioniert. In der Berufsschule habe ich es dann versucht und da ist das Programm eingefroren. Das Netzwerk ist ziemlich groß und so kam ich schon dazu, dass ich vom Broadcasting auf das direkte Senden umgestiegen bin.

dass du Broadcasts gesendet hast und das hat lange gedauert? Also, da ist was faul, einen Broadcast zu senden ist das schnellste, was geht, da hier gar keine DNS-Auflösung gemacht wird! :mahn: Sprich: von Broadcasts auf Unicasts umzusteigen ist sicher keine Verbesserung (zumindest im LAN, per INet gehts natürlich nicht anders)! :shock:

cu
Narses


Narses - Do 08.03.07 00:29

Moin!

So, hab jetzt auch mal über den Code geschaut, aber, ähm, ... :oops: wie sag ich´s diplomatisch, ... das ist nix... :? :hair: Den kannste (und den gedanklichen Ansatz/Idee gleich mit) in die Tonne tun. ;) (bitte nicht persönlich nehmen).

Sag mal, kennst du dieses Tutorial [http://www.delphi-library.de/topic_UDPProtokollChatTutorial+V101_56272.html]? ;)

cu
Narses


Delete - Do 08.03.07 10:13

Okay, danke für das Tutorial...ich muss zu meiner Schande gestehen, dass ich jetzt erst beim Nachschauen gesehen habe, dass du ja die Komponente geschrieben hast :lol:

Bezüglich dem Broadcast: Wie du schon mal erwähnt hattest, liegt das Problem womöglich woanders. Zum Verständnis vielleicht nochmal genaueres über mein Programm. Ich möchte einen Messenger für meine Klasse in der Berufsschule schreiben. Den habe ich zuhause schonmal getestet und da hat soweit alles funktioniert. In der Schule kam dann allerdings das "Einfrier-Phänomen". Wielange dürfte es denn dauern, wenn ich eine Nachricht in ein Netzwerk schicke (selbst wenn die Maske 255.255.255.255 ist)?

Mhmm, jetzt machst du aber meine Motivation runter :( ...ich bin gerade noch in der Schule, schau aber vielleicht gleich schonmal ins Tutorial rein. Ich hoffe dann bin ich etwas schlauer. Welcher Teil von dem Code ist denn nun aber eigentlich schlecht, denn ein gewisser Teil stammte ja auch von dir ;-)


Narses - Do 08.03.07 12:29

Moin!

user profile iconYheeky hat folgendes geschrieben:
ich muss zu meiner Schande gestehen, dass ich jetzt erst beim Nachschauen gesehen habe, dass du ja die Komponente geschrieben hast :lol:

;)

user profile iconYheeky hat folgendes geschrieben:
Zum Verständnis vielleicht nochmal genaueres über mein Programm. Ich möchte einen Messenger für meine Klasse in der Berufsschule schreiben.

Vorab und eigentlich OT, aber trotzdem wichtig: Mir ist ein Fall bekannt, wo der Einsatz eines Chat-Programms in einer Berufsschule (klar, ohne Wissen des Lehrers im Unterricht) zu recht "drastischen Maßnahmen" ggü. den SuS geführt hat... :? Ich hoffe (für dich), dass du weißt, was du da machst! :mahn:

user profile iconYheeky hat folgendes geschrieben:
Bezüglich dem Broadcast: Wie du schon mal erwähnt hattest, liegt das Problem womöglich woanders. [...] In der Schule kam dann allerdings das "Einfrier-Phänomen". Wielange dürfte es denn dauern, wenn ich eine Nachricht in ein Netzwerk schicke (selbst wenn die Maske 255.255.255.255 ist)?

Oo, das sieht nicht gut aus; mir scheint, die Rechner in eurer Schule sind nicht korrekt konfiguriert... :shock: Mach mal ein ipconfig /all 1>C:\ipconfig.txt 2>&1 an einem und pack mal die Ausgabe hier rein (ggfs. als PN, wenn du das nicht öffentlich machen willst).

user profile iconYheeky hat folgendes geschrieben:
Mhmm, jetzt machst du aber meine Motivation runter :( ...
[...]
Welcher Teil von dem Code ist denn nun aber eigentlich schlecht, denn ein gewisser Teil stammte ja auch von dir ;-)

Hm, ich sehe in dem Thread keinen Code von mir (OK, mit Ausnahme der Kompo ;))?! Wie ich schon sagte, der Ansatz scheint mir das Problem zu sein. :|

Aber mach mal die Abfrage und das Tut, dann sehen wir weiter. ;)

cu
Narses


Delete - Do 08.03.07 13:35

user profile iconNarses hat folgendes geschrieben:
Moin!
Vorab und eigentlich OT, aber trotzdem wichtig: Mir ist ein Fall bekannt, wo der Einsatz eines Chat-Programms in einer Berufsschule (klar, ohne Wissen des Lehrers im Unterricht) zu recht "drastischen Maßnahmen" ggü. den SuS geführt hat... :? Ich hoffe (für dich), dass du weißt, was du da machst! :mahn:

Hab ich eigentlich noch nichts von gehört. Was ist den SuS? Was waren das denn für Maßnahmen?

user profile iconNarses hat folgendes geschrieben:
Oo, das sieht nicht gut aus; mir scheint, die Rechner in eurer Schule sind nicht korrekt konfiguriert... :shock: Mach mal ein ipconfig /all 1>C:\ipconfig.txt 2>&1 an einem und pack mal die Ausgabe hier rein (ggfs. als PN, wenn du das nicht öffentlich machen willst).

Gerade passiert ;-)

user profile iconNarses hat folgendes geschrieben:
Hm, ich sehe in dem Thread keinen Code von mir (OK, mit Ausnahme der Kompo ;))?! Wie ich schon sagte, der Ansatz scheint mir das Problem zu sein. :|

Aber mach mal die Abfrage und das Tut, dann sehen wir weiter. ;)

Also das Tutorial sieht schonmal vielversprechend aus. Das Demoprogramm funktioniert auch und das sogar in der Schule! Muss ich den gleichen Aufbau nur noch in meinem Programm verwenden.


Narses - Do 08.03.07 14:17

Moin!

user profile iconYheeky hat folgendes geschrieben:
user profile iconNarses hat folgendes geschrieben:
Moin!
Vorab und eigentlich OT, aber trotzdem wichtig: Mir ist ein Fall bekannt, wo der Einsatz eines Chat-Programms in einer Berufsschule (klar, ohne Wissen des Lehrers im Unterricht) zu recht "drastischen Maßnahmen" ggü. den SuS geführt hat... :? Ich hoffe (für dich), dass du weißt, was du da machst! :mahn:

Hab ich eigentlich noch nichts von gehört. Was ist den SuS? Was waren das denn für Maßnahmen?

Schülerinnen und Schüler ;) Schriftliche Verwarnung für alle an den Ausbilder und der "Urheber der Idee" wurde 1 Woche vom Unterricht ausgeschlossen... :hair: (und IMHO auch völlig zu recht! 8) -> 1. unerlaubter Softwareeinsatz, 2. Betrugswerkzeug, 3. Sabotage an der Schuleinrichtung; Berufsschule ist keine Fun-Veranstaltung, das ist schon halb Job, und da wird nach der Pfeife des Lehrers/Ausbilders getanzt, Punktum!)

user profile iconYheeky hat folgendes geschrieben:
Gerade passiert ;-)

Jau, sieht auch nicht auffällig aus; die anderen Schnittstellen sind ja nicht verbunden und die Verbundene hat eine korrekte Konfiguration. Also, alles OK. ;)

user profile iconYheeky hat folgendes geschrieben:
Also das Tutorial sieht schonmal vielversprechend aus. Das Demoprogramm funktioniert auch und das sogar in der Schule!

Scheint mir also eher, als hättest du "nur" die Kompo unglücklich "Angefasst" oder sowas. ;)

cu
Narses


Robinator - Do 08.03.07 16:04

[quote="user profile iconNarses"]Moin!

user profile iconNarses hat folgendes geschrieben:
Schriftliche Verwarnung für alle an den Ausbilder und der "Urheber der Idee" wurde 1 Woche vom Unterricht ausgeschlossen... :hair: (und IMHO auch völlig zu recht! 8) -> 1. unerlaubter Softwareeinsatz, 2. Betrugswerkzeug, 3. Sabotage an der Schuleinrichtung; Berufsschule ist keine Fun-Veranstaltung, das ist schon halb Job, und da wird nach der Pfeife des Lehrers/Ausbilders getanzt, Punktum!)


Ähm ja... Sabotage.. klar sicher doch. Ich bin ja der Meinung, dass man Schüler für sowas gleich erschiessen sollte :P

Gruss, rob


Delete - Do 08.03.07 16:16

user profile iconNarses hat folgendes geschrieben:
Schülerinnen und Schüler ;) Schriftliche Verwarnung für alle an den Ausbilder und der "Urheber der Idee" wurde 1 Woche vom Unterricht ausgeschlossen... :hair: (und IMHO auch völlig zu recht! 8) -> 1. unerlaubter Softwareeinsatz, 2. Betrugswerkzeug, 3. Sabotage an der Schuleinrichtung; Berufsschule ist keine Fun-Veranstaltung, das ist schon halb Job, und da wird nach der Pfeife des Lehrers/Ausbilders getanzt, Punktum!)

Also im Grunde genommen hast du da schon recht, aber er ist auch für nützliche Sachen gedacht wie z.B. Mitschriften am Laptop können per Datei rübergeschickt werden. Erst aber mal sollte das generelle Prinzip funktionieren ;-)
Also während Arbeiten oder so ist das Ding natürlich tabu und ich denke auch eher, dass wir da als IT-Klasse unterstützt werden, wenn wir uns mit dem Thema Netzwerk auseinander setzen.

user profile iconNarses hat folgendes geschrieben:
Scheint mir also eher, als hättest du "nur" die Kompo unglücklich "Angefasst" oder sowas. ;)
Ja scheint ja so, sonst wäre dein Beispiel ja nicht gegangen. Also brauche ich ja doch nur eine Komponente und nen Thread hast du in deinem Programm auch nicht drin...