Autor Beitrag
Mike_on_Tour
Hält's aus hier
Beiträge: 1



BeitragVerfasst: Do 04.06.09 14:20 
Hallo,

ich versuche mich gerade mit den Indy-Komponenten (Delphi 2005, Indy 10). Mein Testprogramm soll folgende Aufgabe erfüllen:
Das Programm wird auf einem Computer im Netzwerk gestartet. Wird das gleiche Programm auf einem anderen Computer im Netzwerk gestartet, sollen die Programme kurz Daten austauschen. Bei bestimmten Daten soll das zuletzt gestartete Programm beendet werden. Der Ablauf im Programm ist bisher so:
- Programmstart
- alle UDP-Komponenten sind nicht aktiv
- Server2 wird aktiv
- Client1 schickt ein Broadcast an Alle und aktiviert Server1
- Server2 empfängt Daten
- ist die IP-Adresse des Senders identisch mit dem Computer, wird Server2 inaktiv (hat ja eigene Daten erhalten)
- ist die IP-Adresse des Senders nicht identisch mit dem Computer, sendet Client2 Daten an die IP-Adresse des Senders
- Server1 empfängt Daten
- sind die Daten korrekt, sendet Client1 eine Bestätigung zurück
- sind die Daten nicht korrekt, wird Programm beendet

Ich kann das Programm auf einem Computer starten. Ein weiterer Start des gleichen Programms auf einem anderen Computer funktioniert. Wird das gleiche Programm auf einem weiteren Computer gestartet, erhalte ich während des Empfangs von Daten auf Server1 folgende Exception (IdUDPServer1UDPException): "Leinwand/Bild erlaubt kein Zeichnen".

Kann mir jemand weiterhelfen ?

Mike

Vereinfachter Aufbau meines Programms:
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:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
type
  TForm1 = class(TForm)
    IdUDPServer1: TIdUDPServer;
    IdUDPClient1: TIdUDPClient;
    IdUDPClient2: TIdUDPClient;
    IdUDPServer2: TIdUDPServer;
    Button2: TButton;
    procedure Button2Click(Sender: TObject);
    procedure IdUDPServer1UDPRead(Sender: TObject; AData: TBytes; ABinding: TIdSocketHandle);
    procedure IdUDPServer2UDPRead(Sender: TObject; AData: TBytes; ABinding: TIdSocketHandle);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    procedure SendeClient1;
    procedure SendeClient2;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  IdUDPServer1.BroadcastEnabled := true;
  IdUDPServer2.BroadcastEnabled := true;
  IdUDPClient1.BroadcastEnabled := true;
  IdUDPClient2.BroadcastEnabled := true;

  IdUDPServer1.DefaultPort := MYPORT;
  IdUDPServer2.DefaultPort := MYPORT + 1;
  IdUDPClient1.Port := MYPORT + 1;
  IdUDPClient2.Port := MYPORT;

  StarteServer2;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  UDPAnhalten;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  SendeClient1;
end;

procedure TForm1.SendeClient1;
begin
  IdUDPClient1.Active := true;
  IdUDPClient1.Send (Daten);
  IdUDPClient1.Active := false;
end;

procedure TForm1.SendeClient2;
begin
  IdUDPClient2.Active := true;
  IdUDPClient2.Send (Daten);
  IdUDPClient2.Active := false;
end;

procedure TForm1.IdUDPServer1UDPRead(Sender: TObject; AData: TBytes; ABinding: TIdSocketHandle);
begin
  if (AndereIPAdresse)
    then begin
      if (DatenVorhanden)
        then begin
          if (DatenKorrekt)
            then begin
              SendeClient1 (ABinding.PeerIP);
              Exit;
            end
            else begin
              UDPAnhalten;
              Application.Terminate;
              Halt;
            end;
        end;
    end
    else begin
      StoppeServer1;
    end;
end;

procedure TForm1.IdUDPServer2UDPRead(Sender: TObject; AData: TBytes; ABinding: TIdSocketHandle);
var
  sEmpfang : String;
  iPos : Integer;
begin
  if (AndereIPAdresse)
    then begin
      if (DatenVorhanden)
        then begin
          if (DatenAnfrage)
            then begin
              SendeClient2 (ABinding.PeerIP);
              Exit;
            end
          if (DatenBestätigung)
            then begin
              SendeClient2 (ABinding.PeerIP);
              Exit; 
            end
        end;
    end
    else begin
      StoppeServer2;
    end;
end;
Dunkel
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 682

Mac OS X Snow Leopard
Xcode 3.1
BeitragVerfasst: Mi 17.06.09 20:08 
Hallo!

Diese
user profile iconMike_on_Tour hat folgendes geschrieben Zum zitierten Posting springen:
{...} "Leinwand/Bild erlaubt kein Zeichnen".

Fehlermeldung deutet darauf hin, dass ausserhalb des Main-Threads auf das GUI zugegriffen wird. Hast Du in Deinem vereinfachten Beispiel Deines Quelltexts etwaige Threads, welche das Empfangen der Daten handeln, unterschlagen?

_________________
Ich streite einsam mich mit dieser Oberflächenwelt
Gutes sei ein löblich Brot von dem ich zehre - bis zum Tod [Das Ich - Im Ich]
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8554
Erhaltene Danke: 481

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Mi 17.06.09 20:14 
Würde ich auch sagen. Soweit ich weiß, läuft das ganze Server-Gedöns bei den Indys in sekundären Threads. Wenn man von da aus auf die VCL zugreifen will, muss das synchronisiert werden - hier würden sich dann SendMessage-Konstrukte anbieten.

_________________
We are, we were and will not be.