Entwickler-Ecke

Internet / Netzwerk - Indy 9.0 in Unit benutzen


hibbert - Mi 06.09.06 17:40
Titel: Indy 9.0 in Unit benutzen
hi,
ich möchte mir gerne eine Unit schreiben, inder ich einen UDP Server und Clienten drin habe. Dort möchte ich gerne ein eigenen Protokoll entwerfen, damit ich nicht im jedem Netzwerkprogramm immer wieder alles neu einhacken muss.

Nun müsste ich den Server und den Clienten ja mehr oder weniger Dynamisch erzeugen, und genau da fängt es schon wieder an, ich komme einfach nicht weiter :(

Ich habe bis jetzt folgendes probiert:


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:
unit UtNetzwerk;

interface
uses IdBaseComponent, IdComponent, IdUDPBase, IdUDPClient;

  type // wird für den Server benötigt
  TIdSocketHandle = THandle;

type tnetzwerk = class(tobject)
private
var client:TIdUDPClient;
public
function init(port:integer):integer; // 0 = error, 1 = ok
end;


implementation

function tnetzwerk.init(port:integer):integer;
begin
    client:= TIdUDPClient.Create(client);
    client.Port:=port;
end;
end.


Und alles was mir als Fehlermeldung ausgeworfen wird ist folgendes:
Fehlermeldung hat folgendes geschrieben:

---------------------------
Project1
---------------------------
Zugriffsverletzung bei Adresse 0045C774 in Modul 'Project1.exe'. Lesen von Adresse 00000004.
---------------------------
OK
---------------------------


ich habe schon raisgefunden, dass es an dieser Zeile liegt:

Delphi-Quelltext
1:
client:= TIdUDPClient.Create(client);                    


Ich denke mal es liegt an dem Parameter den ich dort eingesetzt habe, leider weiß ich nicht was ich noch dafür einsetzten sollte...

Kann mir jemand vllt auf die Sprünge helfen?

thx hibbert


hibbert - Do 07.09.06 22:24

ok das obige prob hat sich erledigt... musste das ganze als Globale Variable in der Unit deklarieren, das erstellen geht nun also....doch nun habe ich ein weiteres Prob was ich hier gleich anfügen möchte:

nun möchte ich gerne folgendes realisieren:

Delphi-Quelltext
1:
server.OnUDPRead:= ServerRead;                    


dazu habe ich folgendes bis jetzt zusammengebastelt:

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:
type tnetzwerk = class(tobject)
 private
    procedure ServerRead(Sender: TObject; AData: TStream; ABinding: TIdSocketHandle);
 public
    function init(port:integer):integer; // 0 = error, 1 = ok
 end;

function tnetzwerk.init(port:integer):integer;
 begin
    server:= TIdUDPServer.Create(Server);
    server.DefaultPort:=port;
    server.active:= true;
    server.OnUDPRead:= OnUDPRead;
    client:= TIdUDPClient.Create(client);
    client.Port:=port;
 end;

{...}
procedure tNetzwerk.ServerRead(Sender: TObject; AData: TStream; ABinding: TIdSocketHandle);
  var msg:string;
 begin
  AData.Position:=0;
  SetLength(msg,AData.Size);
  AData.ReadBuffer(msg[1],AData.Size);
  showmessage(msg);
 end;


Leider wirft mir der Compiler folgendes an den Kopf:
Compiler hat folgendes geschrieben:
[Fehler] UtNetzwerk.pas(50): E2010 Inkompatible Typen: 'TIdSocketHandle' und 'Cardinal'


Dabei hat die Procedure OnUDPRead exakt die gleichen Parameter als wenn ich die Komponente auf eine Form packen würde, warum also bekomme ich diese Meldung? Kann mir jemand vllt. n Tipp geben?

danke hibbert


hibbert - Mo 11.09.06 16:19

*push* :oops:


ManniTwo - Mo 11.09.06 16:47

hi,

also zunächst mal ist diese zeile merkwürdig:

Delphi-Quelltext
1:
 server.OnUDPRead:= OnUDPRead;                    

da müsste auf der rechten Seite IMHO "ServerRead" stehen, so wie du es weiter oben in deinem Post beschrieben hast.

Vielleicht war das ja schon der Fehler, ansonsten sehe ich im Augenblick auch nichts.

Was ich allerdings zusätzlich merkwürdig finde (was aber mit deinem konkreten Problem nichts zu tun hat) ist , dass du dem Konstruktor das zu instanzierende Objekt übergibst, also:

Delphi-Quelltext
1:
client:= TIdUDPClient.Create(client);                    


das solltest du vielleicht auch noch einmal überprüfen


hibbert - Mo 11.09.06 20:37

user profile iconManniTwo hat folgendes geschrieben:
hi,

also zunächst mal ist diese zeile merkwürdig:

Delphi-Quelltext
1:
 server.OnUDPRead:= OnUDPRead;                    

da müsste auf der rechten Seite IMHO "ServerRead" stehen, so wie du es weiter oben in deinem Post beschrieben hast.

Vielleicht war das ja schon der Fehler, ansonsten sehe ich im Augenblick auch nichts.

Ich habe es verbessert, immer noch der gleiche fehler...

user profile iconManniTwo hat folgendes geschrieben:
Was ich allerdings zusätzlich merkwürdig finde (was aber mit deinem konkreten Problem nichts zu tun hat) ist , dass du dem Konstruktor das zu instanzierende Objekt übergibst, also:

Delphi-Quelltext
1:
client:= TIdUDPClient.Create(client);                    

das solltest du vielleicht auch noch einmal überprüfen

und was sollte ch deiner Meinung nach da ändern? Der Compiler merkert da zumindest nicht...

hibbert


Narses - Mo 11.09.06 20:57

Moin!

user profile iconhibbert hat folgendes geschrieben:
und was sollte ch deiner Meinung nach da ändern? Der Compiler merkert da zumindest nicht...

Nimm NIL. ;)

Und ich schätze, der Fehler liegt hier:
user profile iconhibbert hat folgendes geschrieben:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
unit UtNetzwerk;

interface
uses IdBaseComponent, IdComponent, IdUDPBase, IdUDPClient;

  type // wird für den Server benötigt
  TIdSocketHandle = THandle;

type tnetzwerk = class(tobject)

In meiner Doku ist das aber so deklariert:
TIdSocketHandle = class(TCollectionItem) :shock:

Und das passt auch zu der Fehlermeldung (Cardinal, was THandle ist). ;)

cu
Narses


hibbert - Mo 11.09.06 21:36

hi,
danke erstmal für die hinweise :wink:
ich habe jetzt n paar kleine änderungen gemacht, aber sag mal, hab ich n brett vorm kopf oder so was ähnliches?

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:
  type
  TIdSocketHandle = class(TCollectionItem);

type tnetzwerk = class(tobject)
private
procedure ServerRead(Sender: TObject; AData: TStream; ABinding: TIdSocketHandle);
public
function init(port:integer):integer; // 0 = error, 1 = ok
procedure dest;
end;

implementation

{...}

procedure tNetzwerk.ServerRead(Sender: TObject; AData: TStream; ABinding: TIdSocketHandle);
begin
  {...}
end;

function tnetzwerk.init(port:integer):integer;
begin
    server:= TIdUDPServer.Create(nil);
    server.DefaultPort:=port;
    server.active:= true;
    server.OnUDPRead:= ServerRead;
    client:= TIdUDPClient.Create(nil);
    client.Port:=port;
end;


Der Compiler hat folgendes geschrieben:
[Fehler] UtNetzwerk.pas(48): E2010 Inkompatible Typen: 'IdSocketHandle.TIdSocketHandle' und 'UtNetzwerk.TIdSocketHandle'


Wie soll ich denn nu das schonwieder verstehn? :?

hibbert


Narses - Mo 11.09.06 22:08

Moin!

user profile iconhibbert hat folgendes geschrieben:
Der Compiler hat folgendes geschrieben:
[Fehler] UtNetzwerk.pas(48): E2010 Inkompatible Typen: 'IdSocketHandle.TIdSocketHandle' und 'UtNetzwerk.TIdSocketHandle'

Wie soll ich denn nu das schonwieder verstehn? :?

Na, so wie es da steht? :mrgreen:

Ist denn die Idee so abwegig, dass die Indies gerne ihr eigenes Socket-Handle hätten und du deshalb uses ..., IdSocketHandle; hinzufügen mußt? :roll: (ist doch praktisch eine Typenkollision) ;)

cu
Narses


hibbert - Mo 11.09.06 23:41

moin,
ich habe es mal geändert und siehe da....

Delphi-Quelltext
1:
uses IdBaseComponent, IdComponent, IdUDPBase, IdUDPClient,classes,IdUDPServer,dialogs,IdSocketHandle;                    

Der Compiler hat folgendes geschrieben:
[Fehler] UtNetzwerk.pas(52): E2010 Inkompatible Typen: 'IdSocketHandle.TIdSocketHandle' und 'UtNetzwerk.TIdSocketHandle'

...:shock: noch immer der gleiche fehler. Ich habe sonst nichts weiter verändert...

hibbert


Narses - Di 12.09.06 00:02

Moin!

Roh aus deinem Code zusammengehackt, aber geht durch den Compiler: ;)

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:
unit Unit2;

interface

uses
  Classes, IdSocketHandle, IdUDPServer, IdUDPClient;

type tnetzwerk = class(tobject)
private
procedure ServerRead(Sender: TObject; AData: TStream; ABinding: TIdSocketHandle);
public
function init(port:integer):integer; // 0 = error, 1 = ok
//procedure dest;
end;

var
server: TIdUDPServer;
client: TIdUDPClient;

implementation

procedure tNetzwerk.ServerRead(Sender: TObject; AData: TStream; ABinding: TIdSocketHandle);
begin
//
end;

function tnetzwerk.init(port:integer):integer;
begin
    server:= TIdUDPServer.Create(nil);
    server.DefaultPort:=port;
    server.active:= true;
    server.OnUDPRead:= ServerRead;
    client:= TIdUDPClient.Create(nil);
    client.Port:=port;
end;

end.

cu
Narses


hibbert - Di 12.09.06 01:22

hmmm ok, ich danke dir.

Ich habe einmal deinen Vorschlag versucht und funktioniert auch.

Dann habe ich bei meinem Quelltext mal nachgeforscht und habe festgestellt, dass es die ganze zeit an dieser Deklaration gelegen hat:

Delphi-Quelltext
1:
2:
  type
  TIdSocketHandle = class(TCollectionItem);

oder

Delphi-Quelltext
1:
2:
type
  TIdSocketHandle = Thandle;

:autsch:

naja nun funktioniert es endlich, danke für die hilfe. :D

hibbert