Autor Beitrag
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10181
Erhaltene Danke: 1254

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Fr 03.02.06 02:29 
Der TUdpSockUtil ermöglicht die einfache Kommunikation über das UDP-Protokoll (UDP-Client/Server-Socket) und ist damit praktisch gleichwertig zu einem IdUdpServer und IdUdpClient in einer schlanken Komponente. Die Benutzung ist an TClientSocket bzw. TServerSocket angelehnt, so dass jemand, der gewohnt ist mit den Sockets umzugehen, keine großen Probleme damit haben sollte.
Die Komponente kann im Register "Internet" (da, wo normalerweise auch die Socket-Komponenten drin sind) installiert werden. Natürlich kann die Komponente auch dynamisch erzeugt werden, wenn die Installation in der IDE nicht gewünscht ist.

Grober Funktionsumfang:
  • Senden und Empfangen von UDP-Paketen als String oder über einen Buffer (wie .SendText() bzw. .SendBuf() und .ReceiveText() bzw. .ReceiveBuf() bei den Socket-Komponenten)
  • Benachrichtigung beim Empfang eines UDP-Paketes, bei Sendebereitschaft oder eines Fehlers per Ereignismethode
  • Einfaches Senden von Broadcasts (Nachrichten an alle Hosts im Netzwerk)
  • Einfache Handhabung durch Integration in die Komponentenpalette der IDE
  • Neu ab v2.x: Ansteuerung von UDP-Port-spiegelnden Microcontrollern ist endlich möglich!
Eine ausführliche Anleitung, wie man die Komponente installiert, sowie eine sehr ausführliche Dokumentation dieser und der Quelltext gleich mit, befindet sich im Projaktarchiv im Anhang. Neu: Dazu gibt es noch mehrere Beispielprogramm mit Source: Mini-UDP-Chat, UDP-Chat mit Flüstern, Micro-Controller Ansteuerung, AutoLocalPort-Demo.

In diesem Zusammenhang:
Wer ohne sich durch die Doku-Seiten "durchzuarbeiten" :les: :zwinker: wissen will, was diese Komponente "kann", sollte sich mal die fertige Demoprogramme im Projektarchiv ansehen bzw. ausprobieren, am besten auf mehreren PCs im LAN gleichzeitig. Hier ein Codebeispiel, um schon mal abschätzen zu können, wie einfach die Benutzung ist:
ausblenden 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:
uses
  ..., WinSock; // für den Typ in_addr

// Nachricht an den angegebenen Host senden
procedure TForm1.BtnSendClick(Sender: TObject);
begin
  UdpSockUtil1.RemoteHost := RemoteHost.Text;
  UdpSockUtil1.RemotePort := StrToIntDef(RemotePort.Text,12345);
  UdpSockUtil1.SendText(Input.Text);
end;

// Nachricht an alle Hosts im Netzwerk senden
procedure TForm1.BtnBroadcastClick(Sender: TObject);
begin
  UdpSockUtil1.RemotePort := StrToIntDef(RemotePort.Text,12345);
  UdpSockUtil1.BroadcastText(Input.Text);
end;

// Ereignis: Nachricht eingetroffen
procedure TForm1.UdpSockUtil1Receive(Sender: TObject);
var
  Msg: String;
  vonIP: in_addr; // für diesen Typ:  uses ..., WinSock;  ergänzen!
begin
  // Nachricht einlesen; in vonIP wird die Absender-IP zurückgegeben
  Msg := UdpSockUtil1.ReceiveText(vonIP);
  // Länge der Nachricht, die Nachricht und den Absender anzeigen
  ShowMessage(IntToStr(Length(Msg))+#13+Msg+#13+inet_ntoa(vonIP));
end;


History:
v1.00 vom 03.02.2006
- erste öffentliche Version
v1.01 vom 23.02.2010
- Anpassung an Unicode-Delphi-Versionen
v2.01 vom 13.03.2012
- Milestone-Release, Details in der PDF-Doku im Archiv

Kommentare zu der Komponente sind hier durchaus erwünscht.

cu
Narses
Einloggen, um Attachments anzusehen!


Zuletzt bearbeitet von Narses am Do 12.07.12 10:58, insgesamt 10-mal bearbeitet

Für diesen Beitrag haben gedankt: andrefm, hydemarie, PepitoPerez
Narses Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10181
Erhaltene Danke: 1254

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Di 21.02.06 15:57 
Moin!

Das angekündigte LAN-Chat-Tutorial ist fertig. Viel Erfolg damit. :wink:

cu
Narses
Xantor
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 21



BeitragVerfasst: Di 07.03.06 16:14 
Also - so wie ich es in einem ersten Test sehe, funktioniert das ganz ausgezeichnet. Übrigens, das Sync-Problem etc. taucht mit diesen Komponenten nicht auf. Jedes Packet wird gesendet und auch empfangen und das ganze ohne nennenswerte Latenz. Allerdings taucht nach rund 24000 Bytes ein Fehler auf - ich sende per Broadcast und da werden nicht alle Bytes von allen Rechnern abgeholt - oder liegt das am Sender?
Fehlermeldung: "Ein Socketvorgang konnte nicht ausgeführt werden, da dem SystemPufferspeicher fehlt oder eine Warteschlange voll war (10055), auf API'Bind' "

Hast du da auf anhieb eine Idee, was ich da falsch mache?
Basti2k
Hält's aus hier
Beiträge: 2

WIN XP SP2
Delphi 7 Ent.
BeitragVerfasst: Di 07.03.06 16:55 
Titel: Probleme mit falschem Host
Hallo, ich habe ein Problem. Stellt man mit der UdpSockUtil eine Verbindung zu einem Host her den es nicht gibt, kann man ohne neustarten des Programms keine Verbindung zu einem exsistierenden Host herstellen. Ich wüste auch nicht wie man das umgehen könnte. Ihr vieleicht?


thx
Xantor
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 21



BeitragVerfasst: Di 07.03.06 18:31 
Ich glaub meinen Fehler hab ich gefunden: CloseInactiveSockets muß TRUE sein.
Narses Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10181
Erhaltene Danke: 1254

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Di 21.03.06 02:26 
Moin!

user profile iconXantor hat folgendes geschrieben:
Allerdings taucht nach rund 24000 Bytes ein Fehler auf - ich sende per Broadcast und da werden nicht alle Bytes von allen Rechnern abgeholt - oder liegt das am Sender?
Fehlermeldung: "Ein Socketvorgang konnte nicht ausgeführt werden, da dem SystemPufferspeicher fehlt oder eine Warteschlange voll war (10055), auf API'Bind' "

Hast du da auf anhieb eine Idee, was ich da falsch mache?

Ohne etwas mehr von deinem Quelltext zu sehen, kann ich nicht viel dazu sagen; deiner Beschreibung nach kann ich keinen "Fehler" erahnen... :gruebel: :wink:


user profile iconBasti2k hat folgendes geschrieben:
Hallo, ich habe ein Problem. Stellt man mit der UdpSockUtil eine Verbindung zu einem Host her den es nicht gibt, kann man ohne neustarten des Programms keine Verbindung zu einem exsistierenden Host herstellen.

Da es sich um UDP handelt (verbindungsloses Protokoll), kann man gar keine "Verbindungen" in diesem Sinne herstellen. Vielleicht solltest du dir mal das LAN-Chat-Tut ansehen. :wink: Zeig doch mal etwas von deinem Quelltext, dann kann ich möglicherweise auch mehr dazu sagen. Ein entsprechendes Verhalten konnte ich in meinen Tests nicht nachvollziehen.

cu
Narses
Xantor
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 21



BeitragVerfasst: Di 21.03.06 20:07 
Wie gesagt: CloseInactiveSockets muß TRUE sein - dann funktioniert alles wunderbar
hui1991
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 433

Windows XP, WIndows Vista
Turbo Delphi Explorer| Delphi, PHP,Blitzbasic
BeitragVerfasst: Mi 10.05.06 19:40 
Bei mir fehlt die RTLConsts.
Woher bekomme ich sie?
Narses Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10181
Erhaltene Danke: 1254

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Mi 10.05.06 22:57 
Moin!

Welche Delphi-Version hast du denn? Sollte eigentlich dazugehören... ? :?

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
hui1991
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 433

Windows XP, WIndows Vista
Turbo Delphi Explorer| Delphi, PHP,Blitzbasic
BeitragVerfasst: Do 11.05.06 14:16 
In Delphi 2005 kann ich so wie in der Anleitung das nicht installieren und in Delphi 5 fehlt RTLConsts. Liegt warscheinlich am Delphi 5.
Narses Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10181
Erhaltene Danke: 1254

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Do 11.05.06 14:59 
Moin!

Füg das in der TUdpSockUtil.pas ein, dann kannst du das uses RTLConsts; rausnehmen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
[...]
uses
  Windows, Messages, SysUtils, Classes, WinSock, SyncObjs;

resourcestring
  sWindowsSocketError = 'Windows-Socket-Fehler: %s (%d), auf API ''%s''';
  sCannotCreateSocket = 'Es kann kein neuer Socket erzeugt werden';


const
  USU_WM_ASYNCSELECT = WM_USER +4711// eigene Fensternachricht
[...]

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
hui1991
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 433

Windows XP, WIndows Vista
Turbo Delphi Explorer| Delphi, PHP,Blitzbasic
BeitragVerfasst: Do 11.05.06 15:53 
Ich hab nur noch fehler:
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
[Warnung] UdpSockUtil.pas(230): Konstantenausdruck verletzt untere Grenzen
[Fehler] UdpSockUtil.pas(263): Undefinierter Bezeichner: 'DeallocateHWnd'
[Fehler] UdpSockUtil.pas(301): Undefinierter Bezeichner: 'AllocateHWnd'
[Fehler] UdpSockUtil.pas(301): Nicht genügend wirkliche Parameter
[Warnung] UdpSockUtil.pas(373): Konstantenausdruck verletzt untere Grenzen
[Warnung] UdpSockUtil.pas(387): Der Vergleich ergibt immer Falsch
[Warnung] UdpSockUtil.pas(406): Der Vergleich ergibt immer Falsch
[Warnung] UdpSockUtil.pas(496): Konstantenausdruck verletzt untere Grenzen
[Fataler Fehler] dclusr50.dpk(34): Verwendete Unit 'UdpSockUtil.pas' kann nicht compiliert werden


So ich hoffe das funktioniert bald, ich stehe grad im Stillstand...
...kann in moment nix anderes machen als die Komponete versuchen zu installieren.
Narses Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10181
Erhaltene Danke: 1254

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Do 11.05.06 19:07 
Moin!

Hm, ich hab unterhalb von D6 praktisch keine Erfahrung... :? Was spricht dagegen D7 zu nehmen? ;)

ausblenden Quelltext
1:
2:
[Fehler] UdpSockUtil.pas(263): Undefinierter Bezeichner: 'DeallocateHWnd'
[Fehler] UdpSockUtil.pas(301): Undefinierter Bezeichner: 'AllocateHWnd'

Nimm halt mal das "Classes." weg und schau, ob der Compiler die Referenzen selbst auflösen kann.

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
hui1991
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 433

Windows XP, WIndows Vista
Turbo Delphi Explorer| Delphi, PHP,Blitzbasic
BeitragVerfasst: Do 11.05.06 21:03 
Keine Lust mehr ich besorge mir D7
D5 ist denke ich zu alt. Es wurde ja auch mit D7 getestet.
Es hat dort geklappt.
Weil so komm ich mit meinem Programm net weiter. :cry:
Narses Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10181
Erhaltene Danke: 1254

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Do 22.06.06 15:22 
Moin!

Da die Frage aufkam: "Wie kann ich die Portnummer des Absenders ermitteln?", hier der Ansatz, um diese Information abzugreifen.

Im Quelltext der Komponente steht diese Information beim Lesen aus dem WSA-Puffer bereit, allerdings wird die Portnummer nicht nach Aussen weitergegeben (da die Information sehr selten sinnvoll verwendbar ist):
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:
// vom Empfänger-Socket lesen; Puffer-Variante  
function TUdpSockUtil.ReceiveBuf(var Buf; BufSize: Integer; var RemoteAddr: in_addr; Flags: Integer = 0): Integer;  
  var  
    FromAddr: TSockAddrIn;  
    FromAddrLen: Integer;  
    ErrorCode: Integer;
    RemotePort: Integer;  
begin  
  FSocketLock.Enter;  
  try  
    Result := 0;  
    RemoteAddr.S_addr := -1;  
    if (FRecvSock <> INVALID_SOCKET) then begin  
      FromAddrLen := SizeOf(FromAddr);  
      ZeroMemory(@FromAddr,FromAddrLen);  
      Result := WinSock.RecvFrom(FRecvSock,Buf,BufSize,Flags,FromAddr,FromAddrLen);  
      if (Result = SOCKET_ERROR) then begin  
        ErrorCode := WSAGetLastError;  
        Result := 0;  
        if (ErrorCode <> WSAEWOULDBLOCK) then  
          if Assigned(FOnError) then begin  
            FOnError(Self,ErrorCode);  
            Abort;  
          end  
          else  
            raise EUSUError.CreateResFmt(@sWindowsSocketError,  
              [SysErrorMessage(ErrorCode), ErrorCode, 'RecvFrom']);  
      end  
      else begin
        RemoteAddr := FromAddr.sin_addr;  
        RemotePort := ntohs(FromAddr.sin_port); // Achtung! network-byteorder!
      end;
    end;  
  finally  
    FSocketLock.Leave;  
  end;  
end;

Mit den markierten Zeilen lässt sich die Portadresse ermitteln. Für die Übergabe nach Aussen stehen zwei Ansätze zur Verfügung:
a) Einen weiteren var-Parameter Port: Integer in der Funktionsdeklaration einfügen, oder
b) nicht in_addr, sondern TSockAddrIn als Remote-var-Parameter nehmen, dann wird alles zurückgeliefert.

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
oern
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 142

Linux, Win XP
D7
BeitragVerfasst: Sa 24.06.06 14:15 
Erstmal muss ich loswerden das das die beste netzwerk komponente ist mit der ich je gearbeitet habe :)

Zur zeit versuche ich damit eine record zu versenden, dabei kommt aber die fehler meldung "Windows Socket Fehler: 10014 Ungültige zeiger adresse" diese meldung kann mich mir leider nicht erkären :(
Ich hoffe hier kann mir jemand helfen.

Hier meine Klasse:
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:
115:
116:
117:
118:
119:
unit uglsn_engine;

interface

uses UdpSockUtil, SysUtils, Classes, IdIPWatch, Dialogs;

const
  GLSN_DEFAULTPORT = 42768;
  GLSN_STR = 0;
  GLSN_POS = 1;

type
  TGLS_IPString = string[18];   { size: 18    4*3+3 }
  TGLS_SString = string[20];    { size: 20          }
  TGLS_LString = string[255];   { size: 255         }
  TGLS_Point = packed record    { size: 24    3*8   }
    X,
    Y,
    Z: Double;
  end;

type
  TGLS_NetSend = packed record { 394 }
    C: Integer;
    K: Integer;
    P: Integer;          { 12  }
    Name: TGLS_SString;  { 32  }
    case Integer of
      0:(
       M1,
       M2,
       M3,
       M4,
       M5: TGLS_SString;    { 142 }
       ML: TGLS_LString;    { 387 }
      );
      1:(
       Pos: TGLS_Point;     { 56  }
       Dir: TGLS_Point;     { 70  }
       Speed: Double;
       Power: Double;       { 86  }
      );
  end;

type
  TGLS_OnReceiveEvent = procedure(r: TGLS_NetSend;ip: stringof object;
  TGLS_Network = class (TUdpSockUtil)
  protected
    IP: TIdIPWatch;
    FOnRecieveRecord: TGLS_OnReceiveEvent;
    procedure Receive(Sender: TObject);
  public
    constructor Create(AOwner: TComponent); override;
    procedure BroadcastRecord(r: TGLS_NetSend);
    procedure SendRecord(r: TGLS_NetSend);
  published
    property OnReceiveRecord: TGLS_OnReceiveEvent read FOnRecieveRecord write
                                                          FOnRecieveRecord;
  end;

implementation

uses WinSock;

{ TGLS_Network }

procedure TGLS_Network.BroadcastRecord(r: TGLS_NetSend);
var
  s: string;
begin
  Move(r, s, sizeof(TGLS_NetSend));
  Self.BroadcastText(s); // also auch hier
end;

constructor TGLS_Network.Create(AOwner: TComponent);
begin
  inherited;
  IP:= TIdIPWatch.Create(self);
  IP.HistoryEnabled:= false;
  Self.OnReceive:= Receive;
  Self.LocalPort:= GLSN_DEFAULTPORT;
  Self.RemotePort:= GLSN_DEFAULTPORT;
  Self.Listen:=true;
end;

procedure TGLS_Network.Receive(Sender: TObject);
var
  Len: Integer;
  Msg: String;
  vonIP: in_addr;
  r: TGLS_NetSend;
begin
  // wieviel ist angekommen?
  Len := Self.ReceiveLength;
  if (Len > 0then begin // wenn auch was da ist...

    // Nachricht einlesen; in vonIP wird die Absender-IP zurückgegeben
    Msg := Self.ReceiveText(vonIP);
    if inet_ntoa(vonIP)<>IP.LocalIP then
    begin
      if Len=sizeof(TGLS_NetSend) then begin
        if Assigned(FOnRecieveRecord) then begin
          Move(msg, r, sizeof(TGLS_NetSend));
          FOnRecieveRecord(r, inet_ntoa(vonIP));
        end;
      end;
    end;
  end;
end;

procedure TGLS_Network.SendRecord(r: TGLS_NetSend);
var
  s: string;
begin
  Move(r, s, sizeof(TGLS_NetSend));
  Self.SendText(s);
end;

end.

und der demo aufruf:
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:
unit uglsn_demo;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, uglsn_engine, StdCtrls;

type
  TGLSNWindow = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
    n:TGLS_Network;
    procedure Receive(r: TGLS_NetSend; ip: string);
  end;

var
  GLSNWindow: TGLSNWindow;

implementation

uses WinSock;

{$R *.dfm}

procedure TGLSNWindow.FormCreate(Sender: TObject);
begin
  n:=TGLS_Network.Create(self);
  n.OnReceiveRecord:= Receive;
end;

procedure TGLSNWindow.Receive(r: TGLS_NetSend; ip: string);
begin
  case r.K of
    GLSN_STR:showmessage(r.ML);
    GLSN_POS:;
  end;
end;

procedure TGLSNWindow.Button1Click(Sender: TObject);
var
  r: TGLS_NetSend;
begin
  n.BroadcastRecord(r);// hier der fehler
end;


mfg, Björn

Edit hab das Problem gelöst, jetz klappt es mit records:
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:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
interface

uses
  SysUtils, Classes, IdBaseComponent, IdComponent, IdIPWatch, UdpSockUtil,
  WinSock, Forms, Dialogs;

const
  ALL = '255.255.255.255';
  GLSN_DEFAULTPORT = 42768;
  GLSN_STR = 0;
  GLSN_POS = 1;

type
  TGLS_IPString = string[18];   { size: 18    4*3+3 }
  TGLS_SString = string[20];    { size: 20          }
  TGLS_LString = string[255];   { size: 255         }
  TGLS_Point = packed record    { size: 24    3*8   }
    X,
    Y,
    Z: Double;
  end;

type
  TGLS_NetSend = packed record { 394 }
    C: Integer;
    K: Integer;
    P: Integer;
    Name: TGLS_SString;
    case Integer of
      0:(
       M1,
       M2,
       M3,
       M4,
       M5: TGLS_SString;
       ML: TGLS_LString;
      );
      1:(
       Pos: TGLS_Point;
       Dir: TGLS_Point;
       Speed: Double;
       Power: Double;
      );
  end;

type
  TGLSN_Exception = Exception;
  TGLS_OnReceiveEvent = procedure(r: TGLS_NetSend;ip: stringof object;
  TGLSN_Engine = class(TDataModule)
    UdpSockUtil: TUdpSockUtil;
    IP: TIdIPWatch;
    procedure UdpSockUtilError(Sender: TObject; Error: Integer);
    procedure UdpSockUtilReceive(Sender: TObject);
    procedure DataModuleCreate(Sender: TObject);
  protected
    FOnRecieveRecord: TGLS_OnReceiveEvent;
  public
    { Public-Deklarationen }
    Eceptions: boolean;
    procedure BroadcastRecord(r: TGLS_NetSend);
    procedure SendRecord(r: TGLS_NetSend; toip: string);
  published
    property OnReceiveRecord: TGLS_OnReceiveEvent read FOnRecieveRecord write
                                                          FOnRecieveRecord;
  end;

var
  GLSN_Engine: TGLSN_Engine;

implementation

{$R *.dfm}

procedure TGLSN_Engine.UdpSockUtilError(Sender: TObject; Error: Integer);
begin
  if Eceptions then
     TGLSN_Exception.Create('GLSN Socket Error: '+inttostr(Error));
end;

procedure TGLSN_Engine.UdpSockUtilReceive(Sender: TObject);
var
  Len: Integer;
  Msg: String;
  vonIP: in_addr;
  buffer: TGLS_NetSend;
begin
  // wieviel ist angekommen?
  Len := UdpSockUtil.ReceiveLength;
  if (Len > 0then begin // wenn auch was da ist...
    // Nachricht einlesen; in vonIP wird die Absender-IP zurückgegeben
    UdpSockUtil.ReceiveBuf(buffer, sizeof(buffer), vonIP);
    if inet_ntoa(vonIP)<>IP.LocalIP then
    begin
      if Assigned(FOnRecieveRecord) then begin
        FOnRecieveRecord(buffer, inet_ntoa(vonIP));
      end;
    end;
  end;
end;

procedure TGLSN_Engine.DataModuleCreate(Sender: TObject);
begin
  UdpSockUtil.Listen:=true;
end;

procedure TGLSN_Engine.BroadcastRecord(r: TGLS_NetSend);
var
  s: string;
begin
  s:=UdpSockUtil.RemoteHost;
  UdpSockUtil.RemoteHost:=ALL;
  UdpSockUtil.SendBuf(r, sizeof(r));
  UdpSockUtil.RemoteHost:=s;
end;

procedure TGLSN_Engine.SendRecord(r: TGLS_NetSend; toip: string);
var
  s: string;
begin
  s:=UdpSockUtil.RemoteHost;
  UdpSockUtil.RemoteHost:=toip;
  UdpSockUtil.SendBuf(r, sizeof(r));
  UdpSockUtil.RemoteHost:=s;
end;

end.

_________________
Ich hab eine Signatur
Narses Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10181
Erhaltene Danke: 1254

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Sa 24.06.06 22:21 
Moin!

user profile iconoern hat folgendes geschrieben:
Erstmal muss ich loswerden das das die beste netzwerk komponente ist mit der ich je gearbeitet habe :)

Danke. :D

user profile iconoern hat folgendes geschrieben:
Zur zeit versuche ich damit eine record zu versenden,

Ich möchte allerdings unter Hinweis auf diesen FAQ-Beitrag davon abraten, records zu versenden. :mahn: ;)

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
oern
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 142

Linux, Win XP
D7
BeitragVerfasst: So 25.06.06 12:47 
Zitat:
Ich möchte allerdings unter Hinweis auf diesen FAQ-Beitrag davon abraten, records zu versenden.

Gut, leider sind meine Netzwerk kennise dermaßen gering das ich mich jetzt freue das es klappt, und da ich keine records mit dyn typen verwende trit problem 1 nicht ein, an problem 2 kann ich jedoch nichts machen, erst mal jedenfalles, also werde ich bei meiner lösung bleiben solage sie funktioniert, und mein modul verändern sobald es nötigt wird, aber danke für den Hinweis.

mfg, Björn

_________________
Ich hab eine Signatur
freedy
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 403
Erhaltene Danke: 1

Winows 7
Delphi XE
BeitragVerfasst: Mo 26.06.06 09:54 
Auch wir nutzen die Komponente. Uns gefällt vor allem, dass sie so klein und schlank ist.

Das Versenden von Records macht uns keine Probleme. Durch einen fest definierten Header, den wir jedem UDP-Paket vorwegstellen, umgehen wir das Problem, irgendwo mal Datensalat zu bekommen.

Inzwischen habe ich eine weitere Klasse abgeleitet, die sogar einen Handshake ermöglicht und Daten, die auf mehrere Pakete aufgeteilt wurden, wieder zusammensetzt. Warum das Ganze wo es doch TCP gibt? :-) Fragt meinen Chef. Ich mache schließlich auch nur, was mir gesagt wird. ;-)
Narses Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10181
Erhaltene Danke: 1254

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Mo 26.06.06 11:48 
Moin!

user profile iconfreedy hat folgendes geschrieben:
Auch wir nutzen die Komponente. Uns gefällt vor allem, dass sie so klein und schlank ist.

Nochmal Danke. :D

user profile iconfreedy hat folgendes geschrieben:
Das Versenden von Records macht uns keine Probleme. Durch einen fest definierten Header, den wir jedem UDP-Paket vorwegstellen, umgehen wir das Problem, irgendwo mal Datensalat zu bekommen.

Das Problem liegt leider genau an dieser Stelle: wer noch nie auf Grund von unvorhersehbaren Anforderungen seine "festen Definitionen" wieder gelöst hat, der "werfe das erste Record" (mal frei philosophiert ;)).

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.