Autor Beitrag
tamato76
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Sa 23.10.10 14:37 
Hallo zusammen!

Ich bin nun seit kurzem auf Delphi gewechselt, und programmiere an einer Server Anwendung.
Dabei rufe ich aus der main Unit einen (Server) Thread von der Klasse TThread auf, welcher
sich in einer eigenen Unit befindet.
Diese Anwendung funktioniert auch soweit, aber nur für einen Client.

Um nun mehreren Clients einen Verbindungsaufbau zu erlauben, muss ich im Server Thread wiederum
für jeden Client Verbindungsaufbau einen Thread starten, und genau da liegt mein Problem :-(
Ich habe versucht das MultiThreading mit Create- oder BeginThread zu verwirklichen, leider ohne Erfolg.

Beim Kompellieren bekomme ich eine Fehlermeldung mit ... "access violation at 0x...."
Auch weiß ich nicht, ob ich den Socket Handle richtig an die Thread Funktion übergeben habe ....

Anbei habe ich einen Teil des source codes gepostet. Vielleicht, Hoffentlich kann mir dabei jemand weiterhelfen!!

Vielen Dank schon mal im vorraus!!
Einloggen, um Attachments anzusehen!
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Sa 23.10.10 14:45 
Eines was mir auffällt: Der Callback in BeginThread muss eine einfache Adresse sein. Du übergibst die Adresse einer Methode of object; das läuft wahrscheinlich schief, weil da die Parameterübergabe nicht korrekt verläuft.

Wieso arbeitest du direkt mit dem Betriebssystem; es gibt doch fertige Klassen für TCP Verbindung und Threading.
tamato76 Threadstarter
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Sa 23.10.10 14:59 
Hi Delphifan!

Das heißt, wenn ich meine GetMessage Prozedur nicht von der Klasse ServerTh ... ableite, sollte es funktionieren
wenn ich dich richtig verstehe!??
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Sa 23.10.10 15:36 
user profile icontamato76 hat folgendes geschrieben Zum zitierten Posting springen:
Beim Kompellieren bekomme ich eine Fehlermeldung mit ... "access violation at 0x...."
Beim Kompilieren? Bist du sicher? :gruebel:
Ich vermute doch eher, wenn das Programm läuft, oder?

Wenn ich das bei meinem ersten schnellen Blick (hab grad noch was zu tun) richtig gesehen habe, synchronisierst du PrintLine nicht. Da du vermutlich dort eine visuelle Komponente ansprichst, gibt es entsprechend Probleme.

Ich schaue nachher noch einmal genauer drauf.
tamato76 Threadstarter
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Sa 23.10.10 16:51 
Du hast natürlich recht, die access violation kommt beim ausführen des Programmes!
Und ja .. schreibe über PrintLine die empfangenen Daten in eine Memo Box.

Vielen Dank
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Sa 23.10.10 17:05 
Dass die Fehlermeldung dort kommt, war mir schon klar. Ich wollte nur deutlich machen, dass du schon ein wenig auf die Terminologie achten solltest, denn an anderer Stelle entstehen so vielleicht Missverständnisse. ;-)

Ok, dann kann das so nicht gut gehen, wenn du da auf ein Memo quasi direkt aus dem Thread zugreifst.

Hier einmal ein Beispiel wie sowas richtig funktioniert (im Browser getippt, ungetestet, aber da kann nicht viel schief gehen ;-)):
ausblenden volle Höhe 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:
36:
37:
38:
39:
type
  TExampleMessageEvent = procedure(Sender: TObject; AMsg: string); of object;

  TExample = class(TThread)
  private
    FOnMessage: TExampleMessageEvent;
    FCurrentMessage: string;
    procedure SyncSendTextMessage();
    procedure SendTextMessage(AMsg: string);
  protected
    procedure Execute(); override;
  public
    constructor Create(AOnMessage: TExampleMessageEvent); reintroduce;
  end;

implementation

constructor TExample.Create(AOnMessage: TExampleMessageEvent);
begin
  FOnMessage := AOnMessage;
  inherited Create(False);
end;

procedure TExample.SyncSendTextMessage();
begin
  if Assigned(FOnMessage) then
    FOnMessage(FCurrentMessage);
end;

procedure TExample.SendTextMessage(AMsg: string);
begin
  FCurrentMessage := AMsg;
  Synchronize(SyncSendTextMessage);
end;

procedure TExample.Execute();
begin
  SendTextMessage('Test');
end;
Auf diese Weise kannst du in Execute einfach die Methode SendTextMessage aufrufen, die dann mit dem Hauptthread synchronisiert das Event auslöst.

Durch die Übergabe des Eventhandlers im Konstruktor muss der Thread nicht pausiert gestartet werden. Das kann Probleme machen. Insbesondere, wenn du das in Verbindung mit FreeOnTerminate nutzt.
Flamefire
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: Sa 23.10.10 21:34 
Was soll das?
ausblenden Delphi-Quelltext
1:
if Assigned(PrintLine) then PrintLine(nil);					


Und guck mal nach, was CreateThread macht. Warum erstellst du nicht eine neue Ableitung von TThread, was du dann erzeugst? Wenn schon OOP dann durchgängig ;-)

Und warum die AV (vermutlich) zuschlägt: Du rufst CreateThread mit TServerthread.xxx auf. TServerthread ist das Objekt. Keine Instanz. Demzufolge greift der dann auf falschen Speicherbereich zu.

Ansonten: Debug das doch mal durch und guck, wo der fehler kommt.