Autor Beitrag
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 15.03.12 18:39 
Moin!

Update auf v2.01, Milestone-Release, unbedingt die Doku ansehen! Details und Download wie immer im ersten Beitrag. ;)

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
wdbee
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 628
Erhaltene Danke: 1



BeitragVerfasst: Di 27.11.12 14:14 
Hallo Narses,

bin gerade zufällig über diese Komponente gestolpert.
Da ich demnächst etwas in diese Richtung machen wollte, habe ich mir die Komponente herunter geladen und sie mal als Package installiert.

Was daran wichtig ist? Hehe, ich habe Delphi XE3!

Kurz und gut, (wie die Komponente,) nur in der Datei UdpSockUtil in der uses Anweisung "Messages" durch "Winapi.Messages" ersetzt und alles compiliert.

Werde das mal später mit den Demos testen.

Gruß

Wolf-Dieter

Für diesen Beitrag haben gedankt: Narses
revenger
Hält's aus hier
Beiträge: 1



BeitragVerfasst: Mi 25.12.13 15:48 
Hi,
leider habe ich ein Problem diese Komponente unter Delphi XE4 zu integrieren.

Bekomme beim installieren der Komponente folgende Fehlermeldung:

[dcc32 Fataler Fehler] dclusr.dpk(50): F1026 Datei nicht gefunden: 'C:\Program Files\Embarcadero\RAD Studio\11.0\lib\win32\release\UVersionInfo.dcu

Wäre schön wenn ich dafür eine Lösung finden würde, da ich gerne diese Komponente nutzen möchte.

Gruß und frohe Weihnachten!


Edit:
Ja, neee.. hab nicht darauf geachtet das ich noch andere sachen hinzugefügt hatte bei welchen er den pfad nicht mehr findet!

Alles gut soweit!
OlafSt
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 486
Erhaltene Danke: 99

Win7, Win81, Win10
Tokyo, VS2017
BeitragVerfasst: Do 26.12.13 01:07 
Zur Vervollständigung: Die Komponente funktioniert ausgezeichnet unter XE4 und auch als 64-Bit.

_________________
Lies, was da steht. Denk dann drüber nach. Dann erst fragen.
OlafSt
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 486
Erhaltene Danke: 99

Win7, Win81, Win10
Tokyo, VS2017
BeitragVerfasst: Sa 13.02.16 22:04 
Hallo Freunde,

heute hier mal etwas neues. Die UDP-Komponente funktioniert ausgezeichnet auch mit XE7 - das vorab. Aber ich habe hier ein Phänomen, von dem ich nicht so sicher bin, wie das in den Griff zu bekommen ist.

Nehmen wir eine Anwendung, die mehr oder minder regelmäßig via UDP Daten an ein Ziel schickt. Dies ist gar kein großes Problem und funktioniert stundenlang, tagelang, monatelang. Bis der Inhaber des Ziels auf die Idee kommt, seine feste IP gegen eine DynDNS auszutauschen, weil der Provider nun eine alle-24h-Zwangstrennung vornimmt.

Sobald das Ziel also zwangsgetrennt wurde (und sich automatisch via DynDNS wieder bekanntgibt) erreicht meine sendende Anwendung das Ziel nicht mehr. Die IP wird offenbar nur einmal ermittelt (was ich verstehe, ist ja auch aufwändig), durch das neuverbinden verändert sich die Ziel-IP, meine bisherige ist somit ungültig.

Einfache Lösung wäre nun, vom Ziel ein "ACK" zurücksenden zu lassen, doch ist dies eine Fremdanwendung, dieser Weg ist nicht möglich.

Hat jemand eine andere Option ?

_________________
Lies, was da steht. Denk dann drüber nach. Dann erst fragen.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 14.02.16 00:54 
Wenn du eine feste IP brauchst und sich das nicht anders lösen lässt (Neuverbindung anfordern, ...), bleibt wohl nur auch eine zu benutzen. Dafür könntest du einen virtuellen Server mieten und dort alle Daten 1:1 an deine dynamische Adresse weiterleiten. Das hätte auch den Vorteil, dass du dem Server auch einfach direkt mitteilen kannst, an welche IP er weiterleiten soll, so dass du auch kein DynDNS mehr extern brauchst.
OlafSt
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 486
Erhaltene Danke: 99

Win7, Win81, Win10
Tokyo, VS2017
BeitragVerfasst: Do 03.03.16 13:53 
Eigentlich eine gute Idee, aber vermittel das mal einer Spedition, die keine Ahnung von sowas hat und die durch den eisenharten Wettbewerb jetzt nicht auch noch 2,99/Mon für einen virtuellen Server ausgeben will...

Ich habe mir den Source ein wenig genauer angesehen und kurzerhand ein Flag eingebaut, das die DNS-Auflösung zwangsweise immer wieder neu macht - wenn ich das so möchte. Zwecks Kompatibilität ist dieses Flag immer false, bestehender Code muß also nicht angepaßt werden.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
  TUdpSockUtil = class(TComponent)
  private
  [...]

    FRemoteHost: AnsiString; // dahin senden
    FRemoteAddr: in_addr; // nochmal als IP-Adresse
    FRemotePort: Word; // an diesen Port senden
    FForceResolve: boolean;  //Namensauflösung erzwingen - OST, 28.02.2016
  [...]
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  [...]
    property RemoteAddr: in_addr read GetRemoteAddr write SetRemoteAddr;
    property RecvFlags: Integer read FRecvFlags write FRecvFlags;
    property SendFlags: Integer read FSendFlags write FSendFlags;
    property ForceResolve: boolean read FForceResolve write FForceResolve;  //Resolve erzwingen - OST, 28.02.2016
  [...]
end;


ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
constructor TUdpSockUtil.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Startup;
  [...]
  FRemotePort := 0;
  FCloseInactiveSockets := FALSE;
  FForceResolve:=false;  //Erzwungenes Hostname-Resolving default abgeschaltet - OST, 28.02.2016
  [...]
end;


Im wesentlichen habe ich die Entscheidung "wir haben den Hostnamen schon gesetzt" umgebaut: Alles bleibt beim alten, es sei denn, wir sind durch das Flag gezwungen.

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:
procedure TUdpSockUtil.SetRemoteHost(const Value: AnsiString);
var
   IP: in_addr;
   HostInfo: PHostEnt;
   ErrorCode: Integer;
begin
     //Bei not ForceResolve können wir bei unverändertem Hostnamen gleich raus - OST, 28.02.2016
     if (not FForceResolve) then
        if (FRemoteHost = Value) then
           exit;

     IP.S_addr := inet_addr(PAnsiChar(Value)); // falls der String bereits eine Adresse im IPdotdot-Format ist
     if (IP.S_addr <> Integer(INADDR_NONE)) or (Value = '255.255.255.255'then // sind wir schon fertig, übernehmen
     begin
          if (CheckAddr(IP)) then
          begin
               FRemoteHost := Value;
               FRemoteAddr := IP;
          end;
     end
     else
     begin
          if (Value <> ''then // wurde ein Host angegeben (Leerstring = localhost)
             HostInfo := WinSock.GetHostByName(PAnsiChar(Value)) // Name auflösen
          else
             HostInfo := WinSock.GetHostByName(NIL); // -> localhost abfragen
          if Assigned(HostInfo) then  // Auflösung OK?
          begin
               IP := PInAddr(HostInfo^.h_addr_list^)^;
               if (CheckAddr(IP)) then
               begin
                    FRemoteHost := Value;
                    FRemoteAddr := IP;
               end;
          end
          else
          begin
               ErrorCode := WSAGetLastError;
               if Assigned(FOnResolveError) then
                  FOnResolveError(Self, ErrorCode)
               else
                  raise EUSUError.CreateResFmt(PResStringRec(@sWindowsSocketError),
                                              [SysErrorMessage(ErrorCode), ErrorCode, 'GetHostByName']);
          end;
     end;
end;


Anschließend braucht es noch zwei weitere Ansatzpunkte: Das eigentliche Senden. Sowohl SendText als auch SendBuf setzen einfach den RemoteHost-Namen neu, wenn das Force-Flag gesetzt ist - was dann automatisch zur Neuauflösung führt.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
function TUdpSockUtil.SendBuf(var Buf; BufSize: Integer): Integer;
begin
  FSocketLock.Enter;
  try
    //ggf. Host neu auflösen, wenn wir gezwungen sind - OST, 28.02.2016
    if (FForceResolve) then
       RemoteHost:=FRemoteHost;
    CreateBinding(FMainSocket, FLocalPort, FBroadcast);
    Result := InternalSendBuf(FMainSocket, Buf, BufSize, FSendFlags);
  finally
    CleanupSocket(FMainSocket);
    FSocketLock.Leave;
  end;
end;


ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
function TUdpSockUtil.SendText(const S: AnsiString): Integer;
begin
    //ggf. Host neu auflösen, wenn wir gezwungen sind - OST, 28.02.2016
    if (FForceResolve) then
       RemoteHost:=FRemoteHost;
  Result := InternalSendText(FMainSocket, FLocalPort, FBroadcast, S);
end;


Bisherige Tests haben gezeigt, das es keinen ernsthaften Unterschied in der Laufzeit gibt und auch die Stabilität der UDP-Routinen an sich ist nicht betroffen - muß also gut gearbeitet haben.

_________________
Lies, was da steht. Denk dann drüber nach. Dann erst fragen.

Für diesen Beitrag haben gedankt: Narses
Schwedenbitter
Hält's aus hier
Beiträge: 15

Windows 10

BeitragVerfasst: Mi 14.09.16 12:18 
Ich muss dieses Thema mal aufwärmen:

Ich würde gern basierend auf TUdpSockUtil einen Chat-Programmieren. Das ist mit der Anleitung von Narses eigentlich vergleichsweise einfach. Ich habe aber den Eindruck, dass mir Windows 10 gewaltig dazwischen funkt. So klappt schon der Beispielchat nicht unter Windows 10 - keine Fehlermeldungen, Exceptions oder dergleichen. Wenn ich einen oder mehrere Clients in einer VM (Windows XP) laufen lasse, klappt alles prima.

Interessant ist, dass die Clients unter Windows 10 die UDP-Pakete des XP-Clients empfangen können. Senden sie aber Pakete, scheint Windows 10 diese abzufangen. Sie gelangen also nicht mehr zu den XP-Clients. Bzgl. der Firewall wird man gleich nach dem Online-Gehen von Windows gefragt, ob das Programm im Netzwerk "funken" darf. Selbst das vollständige Abschalten der Windows-Firewall bringt nichts.
Ich habe schon zum Thema UDP und Windows 10 die Suchmaschinen bemüht. Aber eine Lösung oder einen Ansatz dazu habe ich leider nicht gefunden. Ich bin also ziemlich ratlos.

Hat jemand Ideen? Wo kann man dazu Näheres finden?

Gruß, Alex
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 14.09.16 13:31 
Das Beispiel hatte bei mir unter Windows 10 abgesehen von den Multi-Screen Bugs (weil es in Delphi 7 kompiliert ist, ist das Fenster beim Starten außerhalb des Bildschirmbereichs) problemlos funktioniert.

Für diesen Beitrag haben gedankt: Schwedenbitter
Schwedenbitter
Hält's aus hier
Beiträge: 15

Windows 10

BeitragVerfasst: Do 15.09.16 08:07 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Das Beispiel hatte bei mir unter Windows 10 abgesehen von den Multi-Screen Bugs (weil es in Delphi 7 kompiliert ist, ist das Fenster beim Starten außerhalb des Bildschirmbereichs) problemlos funktioniert.


Könntest Du mir bitte mal sagen, welches Windows 10 (also Professional/Home etc.)?

Wir haben hier 11 Rechner mit Windows 10 (alle Professional). 8 von denen noch mit Built 10586 und 3 mit 14393.
Ich habe dann gestern nochmal auf virtuellen Maschinen (XP, 7) und echten getestet. Überall läuft es prima, bloß unter den 10ern nicht.
Ich weiß, dass ist OT und aufgrund meiner Tests gehe ich davon aus, dass es ausnahmslos an Windows 10 liegt. Ich versuche bloß zu verstehen, warum das bei Deinem Windows 10 klappt und hier mit 11 Systemem nicht. Das ist merkwürdig.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 15.09.16 08:23 
Das ist ebenfalls Windows 10 Professional.

Ist das Netzwerk bei euch als privates Netzwerk markiert? Vielleicht steht das auf öffentlich, wo dann standardmäßig stärker abgeschirmt wird.
Schwedenbitter
Hält's aus hier
Beiträge: 15

Windows 10

BeitragVerfasst: Do 22.09.16 17:12 
Ich habe das Problem gefunden. Entschuldigt, dass ich die Pferde scheu gemacht habe und danke für Eure Hilfsbereitschaft!
Das Problem war/ist VirtualBox. Es legt einen virtuellen Netzerk-Adapter an mit einem anderen Subnetz (z.B. 192.168.56 statt 192.168.178). TUdpSockUtil nutzt nun diesen Adapter, womit die UDP-Pakete nicht mehr ankommen. Wenn ich jetzt von Hand die IP-Adresse des jeweiligen Adapters beim property BindTo eintrage, klappt es.
Allerdings hatte ich die ausführliche pdf-Datei zu TUdpSockUtil so verstanden, dass es hätte trotzdem klappen sollen/müssen, wenn man Brodcast := True setzt. Das tut es merkwürdiger Weise aber nicht.

Das Problem bringt mich zu einer weiteren Frage:
Wir haben 2 Standorte mittels 2 FritzBoxen via VPN verbunden. Diese haben daher notwendiger Weise ebenfalls 2 verschiedene Subnetze. Gäbe es dafür eine Lösung oder kann ich UDP gleich ad acta legen?

Ich hätte sonst erstmal versucht, ob die FritzBoxen überhaupt UDP-Pakete durchleiten.
Schwedenbitter
Hält's aus hier
Beiträge: 15

Windows 10

BeitragVerfasst: Mo 10.10.16 18:54 
Ich muss leider nochmal pushen.

Ich komme mit unseren über VPN verbundenen Netzen nicht weiter. Es handelt sich dabei um zwei Subnetze mit 192.168.x.0. Innerhalb des nahen Subnetzes tut es ein Broadcast auf 192.168.x.255 bei der Maske 255.255.255.0. Leider komme ich möglicher Weise an den Routern nicht vorbei. Laut AVM wird innerhalb des VPN nichts geblockt. Damit müsste eigentlich ein Broadcast an 255.255.255.255 auch auf dem entfernten Subnetz ankommen, tut es aber nicht.

Zur Abhilfe war mein Plan daher, beim An- und Abmelden, statt eines Broadcast an alle möglichen Clients zu senden, die sich aus dem Adressbereich 192.168.x.y ergeben. Das dauert ca. 2 Sekunden, womit ich leben könnte. Es kommt aber nichts an - nicht einmal mehr im hiesigen Netz.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
For SNet:= 0 To 255 Do
Begin
  For IP:= 1 To 254 Do
  Begin
    UDPSocket.RemoteHost:= '192.168.' + IntToStr(SNet) + ' .' + IntToStr(IP);
    UDPSocket.SendText(SendText);
  End;
End;
Application.ProcessMessages;


Im Quellcode von UdpSockUtil.pas steht in Zeile 472 der Kommentar "// im Broadcast-Mode ist jede Adresse erlaubt, da auch Subnet-Broadcasts gehen". Interessant ist für mich der 2. Teil des Satzes.

Wie geht denn so ein Subnet-Broadcast?
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 10.10.16 22:12 
Moin!

Klingt für mich wie ein Verständnisproblem mit IP-Netzen. :nixweiss:
user profile icona.winzer hat folgendes geschrieben Zum zitierten Posting springen:
Ich komme mit unseren über VPN verbundenen Netzen nicht weiter. Es handelt sich dabei um zwei Subnetze mit 192.168.x.0. Innerhalb des nahen Subnetzes tut es ein Broadcast auf 192.168.x.255 bei der Maske 255.255.255.0. Leider komme ich möglicher Weise an den Routern nicht vorbei. Laut AVM wird innerhalb des VPN nichts geblockt. Damit müsste eigentlich ein Broadcast an 255.255.255.255 auch auf dem entfernten Subnetz ankommen, tut es aber nicht.
Und das ist by-design so, es ist ein anderes Netz, also kann ein UDP-Subnet-Broadcast da nicht ankommen. Nur weil du eine Route definiert hast, wie (gerichtete) Pakete einen Netzübergang machen können, gilt das nicht für Nachrichten an ein Subnetz (=Broadcast). :idea: Üblicherweise filtert man darüber hinaus, selbst wenn das klappen sollte, UDP-Broadcasts an Routern raus, damit geschwätzige Protokolle nicht das Netz "zulabern". ;) (Routen definiert man üblicherweise über WAN-Stecken, die eine andere, meist deutlich schlechtere, Bandbreite haben) Kurz: Broadcasts kommen nur im gleichen Subnetz an (alles, was auf die Subnetmask passt, an die der Socket gebunden ist - deshalb heißt die so).

Um da irgendwas sinnvolles empfehlen zu können, habe ich zu wenig Durchblick, wie die Gegebenheiten bei euch sind und was da genau passieren soll. Da möchte ich lieber keine halbgaren Dunst-Empfehlungen aussprechen, das bringt nix. :?

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Schwedenbitter
Hält's aus hier
Beiträge: 15

Windows 10

BeitragVerfasst: Mo 17.10.16 20:58 
Danke. OK. Das mit dem Broadcast habe ich verstanden - es geht nicht und ich werde es nicht ändern können.

Allerdings habe ich da eine weitere Frage: offenbar ist ein gerichtetes Senden per UDP möglich. Also das Senden eines UDP-Paketes an eine bekannte IP-Adresse im entfernten Netz. Ich habe das getestet und es klappt:
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:
30:
Procedure TMainForm.UDPSocketReceive(Sender: TObject);
Var
  Data        : TStringList;
  vonIP        : in_addr;
  Current      : TCmdToken;              // empfangenes Kommando
  I          : Integer;
  S          : String;
Begin
  Data:= TStringList.Create;
  Try
    Data.Text:= String(UDPSocket.ReceiveText(vonIP));// Daten auslesen
    If (Data.Count > 1Then              // mind. 2 Datenpakete
    Begin
      If (Data.Strings[0] = APP_ID) Then      // von unserem Client
      Begin
        Current:= GetCmdToken(Data.Strings[1]);
        If (Data.Count >= Succ(Syntax[Current].ArgCount)) Then
          Execute(Current, Data, vonIP);    // gültigen Befehl abarbeiten
      End;
    End
    Else
    Begin
      S:= '';
      For I:= 1 To Length(Data.Text) Do S:= S + IntToHex(Byte(Data.Text[I]), 2) + ' ';
      Loggen('''FREMDES PAKET: ' + Trim(S));
    End;
  Finally
    Data.Free;
  End;
End;

Wenn ich jetzt auf einem Linux-Rechner im entfernten Netz ein iperf --port 12345 --udp --num 100 --client 192.168.1.48 absetze, kommt das in meinem Netz hier an. Es sind zwar keine 1.470 Bytes, die iperf standardmäßig rübersendet, aber es kommt immerhin etwas an (FREMDES PAKET: FF FF FF FF 58 05 1D EE 0D 0A).


iperf bietet aber nicht nur einen Client, sondern auch einen Server an, der auf diesem Port lauschen kann. Wenn ich jetzt mit meinem Delphi-Programm
ausblenden Delphi-Quelltext
1:
2:
UDPSocket.RemoteHost:= '192.168.255.35';
UDPSocket.SendText:= 'Blablablubb';
sende, kommt nichts an. Ich verstehe es so, dass RemoteHost den Empfänger enthält. Oder sehe ich das falsch?
Schwedenbitter
Hält's aus hier
Beiträge: 15

Windows 10

BeitragVerfasst: Mo 17.10.16 21:29 
Ich nehme alles zurück! Die Pakete kommen auf dem Linux-Rechner an, wenn man die Firewall deaktiviert. Ich will wirklich nicht pushen. Ich schreibe bloß gleich, damit nicht jemand noch mehr in die falsche Richtung denkt.

Das verwirrt mich jetzt allerdings. Wenn man das Delphi-Programm in der IDE und auch isoliert startet, wird man unter (in meinem Fall) Windows 10 gefragt, ob man Traffic zulassen will. Das klicke ich brav an. Was kann man denn noch mehr machen?
Denn irgendwann wird es auch unpraktikabel. Wenn man ein Programm z.B. verkaufen will und dann zig Einstellungen ändern und das in ein Handbuch schreiben muss. Außerdem kommt das Paket an dem Rechner rein und es geht auch raus...
Jetzt bin ich völlig ratlos!
rage2002
Hält's aus hier
Beiträge: 1
Erhaltene Danke: 1



BeitragVerfasst: Do 09.03.17 13:05 
Hallo
Vielen Dank für Deine Arbeit. Ich benutze einen MC mit unterschiedlichen Lan-Controllern und habe mir mit den üblichen UDP-Komponeten die Zähne ausgebissen ein einer Kommunikation am selben Port. Dank Deiner Komponente läuft es jetzt.

cu rage

Für diesen Beitrag haben gedankt: Narses