Autor Thema: UDP Datagramme empfangen  (Gelesen 1549 mal)

Offline herrmannj

  • Global Moderator
  • Hero Member
  • ****
  • Beiträge: 4940
Antw:UDP Datagramme empfangen
« Antwort #15 am: 26 Januar 2019, 21:46:10 »
klar:)

Aber das ist eine andere als oben ?  Brauchst Du jetzt Multicast oder Broadcast ? https://aseith.com/display/KB/Unterschiede+zwischen+Unicast%2C+Broadcast%2C+Multicast+und+Anycast
smartVisu mit fronthem, einiges an HM, RFXTRX, Oregon, CUL, Homeeasy, ganz viele LED + Diverse

Offline Sailor

  • Developer
  • Hero Member
  • ****
  • Beiträge: 1387
  • und es werden immer mehr...
Antw:UDP Datagramme empfangen
« Antwort #16 am: 27 Januar 2019, 19:46:59 »
Hallo Hermann
klar:)

Mein letzter Post hat den richtigen Auszug von wireshark von genau dem Gerät, was ich in dem Modul versuche abzuhören.

Für mich gibt es nur zwei Möglichkeiten
a) entweder lese ich mich jetzt ganz langwierig in das Thema UDP bzw Multicast datagramme ein
oder
b) ich hoffe auf einen Experten in dieser Runde, der mir die entsprechenden Code Zeilen korrigiert.

Wie gesagt, ich habe von diesem Thema 0 Schimmer.

Danke dir!

Gruss
   Sailor
******************************
Raspberry Pi mit DbLog, HomeMatic HMLAN
13x HM-SEC-SC; 11x HM-TC-IT-WM-W-EU; 13x HM-CC-RT-DN; 03x HM-Sec-SD; 01x HM-WDS10-TH-O; km200 mit Buderus GB172

Offline CoolTux

  • Developer
  • Hero Member
  • ****
  • Beiträge: 19535
Antw:UDP Datagramme empfangen
« Antwort #17 am: 28 Januar 2019, 08:04:17 »
So,

habe mal das Datagram von einem Besitzer bekommen:
Internet Protocol Version 4, Src: 192.168.xx.xx, Dst: 255.255.255.255
User Datagram Protocol, Src Port: 3074, Dst Port: 35344

bzw.

Internet Protocol Version 4, Src: 192.168.xx.xx, Dst: 255.255.255.255
User Datagram Protocol, Src Port: 3074, Dst Port: 6524

Könnt Ihr als Experten damit was anfangen?

Gruss
    Sailor

Sieht ganz anders aus.
192.168. ist die IP Deines DoorBird? Und der Port ist auch immer der selbe. Kann man da nicht einfach eine UDP Clientverbindung zu dem Teil auf machen?

my $socket = new IO::Socket::INET   (   PeerHost => $host,
                                            PeerPort => $port,
                                            Proto => 'udp',
                                            Timeout => $timeout
                                        )
        or return Log3 $name, 4, " ($name) Couldn't connect to $host:$port";      # open Socket
       
    $hash->{FD}    = $socket->fileno();
    $hash->{CD}    = $socket;         # sysread / close won't work on fileno
    $selectlist{$name} = $hash;
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.me/MOldenburg
FHEM GitHub: https://github.com/fhem/
kein Support für cfg Editierer

Offline Sailor

  • Developer
  • Hero Member
  • ****
  • Beiträge: 1387
  • und es werden immer mehr...
Antw:UDP Datagramme empfangen
« Antwort #18 am: 28 Januar 2019, 11:16:00 »
Hallo CoolTux

Sieht ganz anders aus.
192.168. ist die IP Deines DoorBird? Und der Port ist auch immer der selbe. Kann man da nicht einfach eine UDP Clientverbindung zu dem Teil auf machen?

Can't call method "fileno" on an undefined value at ./FHEM/73_DoorBird.pm line 176.
OK, werde ich versuchen, aber wie vermeide ich bei einer Neu-Definition des Device nach einem Neustart (das funktioniert wohl noch), dass mein fhem - System mit der Fehlermeldung oben abschmiert?
Der Fehler ist auf anderen Systemen reproduzierbar...

Gruss
    Sailor
******************************
Raspberry Pi mit DbLog, HomeMatic HMLAN
13x HM-SEC-SC; 11x HM-TC-IT-WM-W-EU; 13x HM-CC-RT-DN; 03x HM-Sec-SD; 01x HM-WDS10-TH-O; km200 mit Buderus GB172

Offline CoolTux

  • Developer
  • Hero Member
  • ****
  • Beiträge: 19535
Antw:UDP Datagramme empfangen
« Antwort #19 am: 28 Januar 2019, 11:23:43 »
Genau so wie ich es geschrieben habe.

or return Log3 $name, 4, " ($name) Couldn't connect to $host:$port";
Wenn Du nur schreibst
my $conn = IO::Socket::INET->new(Proto=>"udp",LocalPort=>3702);Aber nicht prüfst ob das erstellen des Objektes auch wirklich geklappt hat dann wird das nichts.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.me/MOldenburg
FHEM GitHub: https://github.com/fhem/
kein Support für cfg Editierer

Offline herrmannj

  • Global Moderator
  • Hero Member
  • ****
  • Beiträge: 4940
Antw:UDP Datagramme empfangen
« Antwort #20 am: 28 Januar 2019, 11:39:55 »
ich vermute mal das reuse port fehlt, kann das aber nur raten.

Ganz um das einlesen wirst Du nicht herumkommen, wie willst Du sonst bugs in Deinem code finden wenn Du nicht verstehst was er tut? (Genau das ist was gerade passiert... Glaub ich..)

Sowohl Andre als auch ich haben funktionierenden code zum abtippen in die Runde geworfen. Aber minimale Abweichungen davon können zu Fehlern, vmtl trivialen, führen - das ist aber auch normal.

Stell doch Deinen code mal komplett ein. Ich kann Dir den udp Teil sonst schon schreiben, aber was hilft Dir das dann?
smartVisu mit fronthem, einiges an HM, RFXTRX, Oregon, CUL, Homeeasy, ganz viele LED + Diverse

Offline Sailor

  • Developer
  • Hero Member
  • ****
  • Beiträge: 1387
  • und es werden immer mehr...
Antw:UDP Datagramme empfangen
« Antwort #21 am: 01 Februar 2019, 07:32:37 »
Moin zusammen

ich vermute mal das reuse port fehlt, kann das aber nur raten.

Der folgende Code wird in der DoorBird_Define() aufgerufen bzw in der DoorBird_Init() definiert / verwiesen:
sub DoorBird_Initialize($)
{
...
    $hash->{ReadFn}          = "DoorBird_Read";
...
}

sub DoorBird_OpenSocketConn($) {
my ($hash) = @_;
my $name = $hash->{NAME};
my $conn;


### Check if json can be parsed into hash
eval
{
$conn = new IO::Socket::INET (
PeerAddr  => '255.255.255.255',
PeerPort  =>  6524
Proto     => 'udp',
Broadcast => 1
);
1;
}
or do
{
### Log Entry for debugging purposes
Log3 $name, 3, $name. " : DoorBird_OpenSocketConn - Socket Connection cannot be established";

return
};

### Log Entry for debugging purposes
Log3 $name, 5, $name. " : DoorBird_OpenSocketConn - Socket Connection has been established";
Log3 $name, 5, $name. " : DoorBird_OpenSocketConn - SocketConnection        : " . $conn;

$hash->{FD}    = $conn->fileno();
$hash->{CD} = $conn;
$selectlist{$name} = $hash;

return
}

sub DoorBird_Read($) {
my ($hash) = @_;
my $name = $hash->{NAME};
my $buf;
my $data;

$hash->{CD}->recv($buf, 16);
$data = unpack('H*', $buf);

### Log Entry for debugging purposes
Log3 $name, 5, $name. " : DoorBird_Read - UDP Client said                   : " . $data;

Dispatch($hash, $buf);
}

führt zwar zu einem Anlegen einer Verbindung
DoorBird_OpenSocketConn - Socket Connection has been established
DoorBird_OpenSocketConn - SocketConnection        : IO::Socket::INET=GLOB(0x725d0d0)

aber das DoorBird_Read kommt dennoch nicht zum Zuge, sobald im LAN folgende Messages auftauchen:
Internet Protocol Version 4, Src: 192.168.xx.xx, Dst: 255.255.255.255
User Datagram Protocol, Src Port: 3074, Dst Port: 6524

Ich habe mich jetzt ein wenig in Broadcast, Unicast und Multicast eingelesen und habe mir von den jeweiligen Testern und Besitzern bestätigen lassen, dass der DoorBird ohne irgendwelche weiteren Router/Firewall am gleichen Switch hängen.

Eigentlich müsste doch was kommen...

Die von Dir und André in die Runde geworfenen Code-Snippets zielen, sofern ich das richtig verstanden habe, auf Unicast bzw. Multicast ab und ist wohl nicht mit dem o.g. Broadcast kompatibel.

Habt Ihr da noch eine andere Idee?

Danke

Gruß
    Sailor
******************************
Raspberry Pi mit DbLog, HomeMatic HMLAN
13x HM-SEC-SC; 11x HM-TC-IT-WM-W-EU; 13x HM-CC-RT-DN; 03x HM-Sec-SD; 01x HM-WDS10-TH-O; km200 mit Buderus GB172

Offline herrmannj

  • Global Moderator
  • Hero Member
  • ****
  • Beiträge: 4940
Antw:UDP Datagramme empfangen
« Antwort #22 am: 01 Februar 2019, 14:19:43 »
Moin Sailor,

Wenn Du den socket via IO::Socket::INET (https://perldoc.perl.org/IO/Socket/INET.html) erstellen möchtest:

PeerAddr, PeerPort, Broadcast  sind dafür nicht erforderlich.

Stattdessen musst Du LocalPort auf den Port setzen welcher empfängt (6524), "UDP" bleibt natürlich.

Reuse port kann vmtl in diesem Szenario entfallen. Ich würde den usern empfehlen den FHEM Server komplett neu zu starten wenn Du das angepasst hast bevor sie testen.
smartVisu mit fronthem, einiges an HM, RFXTRX, Oregon, CUL, Homeeasy, ganz viele LED + Diverse

Offline Sailor

  • Developer
  • Hero Member
  • ****
  • Beiträge: 1387
  • und es werden immer mehr...
Antw:UDP Datagramme empfangen
« Antwort #23 am: 01 Februar 2019, 20:45:12 »
Hallo Herrmann

Wenn Du den socket via IO::Socket::INET (https://perldoc.perl.org/IO/Socket/INET.html) erstellen möchtest:
PeerAddr, PeerPort, Broadcast  sind dafür nicht erforderlich.
Stattdessen musst Du LocalPort auf den Port setzen welcher empfängt (6524), "UDP" bleibt natürlich.
Reuse port kann vmtl in diesem Szenario entfallen. Ich würde den usern empfehlen den FHEM Server komplett neu zu starten wenn Du das angepasst hast bevor sie testen.

Mit dem Code

$conn = new IO::Socket::INET (
Listen    => 5,
LocalAddr => 'localhost',
LocalPort => 6524,
Proto     => 'udp'
);

sowie

$conn = new IO::Socket::INET (
Listen    => 5,
LocalAddr => '192.168.178.vomfhemServer',
LocalPort => 6524,
Proto     => 'udp'
);

bzw.

$conn = new IO::Socket::INET (
LocalPort => 6524,
Proto     => 'udp'
);

lassen sich keine Socket - Verbindungen aufbauen.

Das Beispiel
$conn = new IO::Socket::INET (
PeerAddr => 'www.perl.org',
PeerPort => 'http(80)',
Proto    => 'tcp'
);
lässt sich aufbauen und es kommt über DoorBird_Read rein:

Unknown code , help me!
DoorBird_Read - UDP Client said buf               :
DoorBird_Read - UDP Client said data              :
dispatch

Es ist zum Mäusemelken...

Gruss
    Sailor
******************************
Raspberry Pi mit DbLog, HomeMatic HMLAN
13x HM-SEC-SC; 11x HM-TC-IT-WM-W-EU; 13x HM-CC-RT-DN; 03x HM-Sec-SD; 01x HM-WDS10-TH-O; km200 mit Buderus GB172

Offline herrmannj

  • Global Moderator
  • Hero Member
  • ****
  • Beiträge: 4940
Antw:UDP Datagramme empfangen
« Antwort #24 am: 01 Februar 2019, 21:23:39 »
Was heist denn "lassen sich keine Socket - Verbindungen aufbauen." ?

UDP ist ein verbindungsloses Protokoll.

Ein Beispiel:
package main;

use strict;
use warnings;
use utf8;

use IO::Socket::INET;
use Data::Dumper;

my $conn = new IO::Socket::INET (
LocalPort => 6524,
Proto     => 'udp'
) or die("failed...");

print Dumper $conn;

1;
Ausgabe:
$VAR1 = bless( \*Symbol::GEN0, 'IO::Socket::INET' );Funktioniert.


Nachtrag: ergänzt, ein receive
package main;

use strict;
use warnings;
use utf8;

use IO::Socket::INET;
use Data::Dumper;

my $conn = new IO::Socket::INET (
LocalPort => 6524,
Proto     => 'udp'
) or die("failed...");

print Dumper $conn;

my ($data,$flags);
$conn->recv($data, 1024, $flags);
print "Received datagram from ", $conn->peerhost,", flags ", $flags || "none", ": $data\n";

1;
« Letzte Änderung: 01 Februar 2019, 21:29:29 von herrmannj »
smartVisu mit fronthem, einiges an HM, RFXTRX, Oregon, CUL, Homeeasy, ganz viele LED + Diverse

Offline justme1968

  • Developer
  • Hero Member
  • ****
  • Beiträge: 19053
Antw:UDP Datagramme empfangen
« Antwort #25 am: 01 Februar 2019, 21:34:22 »
ich weiss nicht ob dein code oben noch aktuell ist, aber da fehlt ein , hinter 6524 deshalb geht das eval schief.

übrigens: du brauchst du kein eval. einfach $conn auswerten reicht.

wenn du PeerAddr und PeerPort verwendest baust du eine verbindung zu einem ziel auf das auf eine verbindung wartet.

wenn du beides weg lässt wartest du das dir jemand daten schickt.

wenn du auf reagieren willst wenn dir jemand was sendet braucht du letzteres und du kannst beide fälle nicht vergleichen.

FHEM5.4,DS1512+,2xCULv3,DS9490R,HMLAN,2xRasPi
CUL_HM:HM-LC-Bl1PBU-FM,HM-LC-Sw1PBU-FM,HM-SEC-MDIR,HM-SEC-RHS
HUEBridge,HUEDevice:LCT001,LLC001,LLC006,LWL001
OWDevice:DS1420,DS18B20,DS2406,DS2423
FS20:fs20as4,fs20bs,fs20di
AKCP:THS01,WS15
CUL_WS:S300TH

Offline Sailor

  • Developer
  • Hero Member
  • ****
  • Beiträge: 1387
  • und es werden immer mehr...
Antw:UDP Datagramme empfangen
« Antwort #26 am: 01 Februar 2019, 22:38:23 »
Was heist denn "lassen sich keine Socket - Verbindungen aufbauen." ?

UDP ist ein verbindungsloses Protokoll.

Ein Beispiel:
package main;

use strict;
use warnings;
use utf8;

use IO::Socket::INET;
use Data::Dumper;

my $conn = new IO::Socket::INET (
LocalPort => 6524,
Proto     => 'udp'
) or die("failed...");

Genau an dieser Stelle steht dann ein
failed... at ./FHEM/73_DoorBird.pm line 627.
im fhem-Log und fhem ist abgestürzt...
Daher hatte ich das im eval.

Nehmen wir mal an, ich würde im Wireshark laufend folgende Meldungen zum Testen nehmen wollen:

192.168.178.21 239.255.255.250 UDP 1265 3702 → 3702 Len=4183

Mir ist bewusst, dass die "239.255.255.250" keine Broadcast - Adresse im eigentlichen Sinne ist, aber das dürfte bei dem Code unten eigentlich keine Rolle spielen, da er ja scheinbar auf alles reagiert was als Protokol "udp" gekennzeichnet und auf Port 3702 liegt.

Oder irre ich mich da?

###START###### Open UDP socket connection #####################################################################START####
sub DoorBird_OpenSocketConn($) {
my ($hash) = @_;
my $name = $hash->{NAME};
my $conn;
my $port = $hash->{helper}{UdpPort};
my $url  = $hash->{helper}{URL};
   $url  =~ s/:.*//;

### Log Entry for debugging purposes
Log3 $name, 5, $name. " : DoorBird_OpenSocketConn - url                     : " . $url;
Log3 $name, 5, $name. " : DoorBird_OpenSocketConn - port                    : " . $port;

## Check if connection can be opened
eval
{
$conn = new IO::Socket::INET (
LocalPort => 3702,
Proto     => 'udp'
);
1;
}
or do
{
### Log Entry for debugging purposes
Log3 $name, 3, $name. " : DoorBird_OpenSocketConn - IO::Socket::INET Error  : " . $@;

return
};


Log3 $name, 5, $name. " : DoorBird_OpenSocketConn - SocketConnection        : " . Dumper($conn);


if (defined($conn)) {
$hash->{FD}    = $conn->fileno();
$hash->{CD} = $conn;
$selectlist{$name} = $hash;

### Log Entry for debugging purposes
Log3 $name, 5, $name. " : DoorBird_OpenSocketConn - Socket Connection has been established";
}
else {
### Log Entry for debugging purposes
Log3 $name, 5, $name. " : DoorBird_OpenSocketConn - Socket Connection has NOT been established";
}
return
}
####END####### Open UDP socket connection ######################################################################END#####

###START###### After return of UDP message ####################################################################START####
sub DoorBird_Read($) {
my ($hash) = @_;
my $name = $hash->{NAME};
my $buf;
my $flags;
my $data;

my $PeerHost = $hash->{CD}->peerhost;

$hash->{CD}->recv($buf, 1024, $flags);
$data = unpack('H*', $buf);

### Log Entry for debugging purposes
Log3 $name, 5, $name. " : DoorBird_Read - UDP Client said PeerHost          : " . $PeerHost;
Log3 $name, 5, $name. " : DoorBird_Read - UDP Client said buf               : " . $buf;
Log3 $name, 5, $name. " : DoorBird_Read - UDP Client said flags             : " . $flags;
Log3 $name, 5, $name. " : DoorBird_Read - UDP Client said data              : " . $data;

Dispatch($hash, $buf);
}
####END####### After return of UDP message #####################################################################END#####

a) Einen Neustart per "sudo reboot" erzwungen,
b) das DoorBird Device neu definiert,
und folgendes im Log entdeckt:

DoorBird_OpenSocketConn - url                     : 192.168.178.21
DoorBird_OpenSocketConn - port                    : 3702
DoorBird_OpenSocketConn - SocketConnection        : $VAR1 = undef;

DoorBird_OpenSocketConn - Socket Connection has NOT been established


## Check if connection can be opened
$conn = eval { ...
kommt zum gleichen Ergebnis.

Zumindest kommt es nicht zum fhem Absturz...

Warum klappt das bei Herrmann seiner perl-Routine und nicht innerhalb von einem fhem - Modul.

Habe ich irgendwas am RasPi nicht richtig installiert (Debian Pakete, Perl libs, ethernet card) oder lässt fhem irgendetwas nicht zu?
Rätsel über Rätsel... :-[

Vielleicht ist dies ein guter Zeitpunkt die Basics abzuklopfen.

Gruss
    Sailor
******************************
Raspberry Pi mit DbLog, HomeMatic HMLAN
13x HM-SEC-SC; 11x HM-TC-IT-WM-W-EU; 13x HM-CC-RT-DN; 03x HM-Sec-SD; 01x HM-WDS10-TH-O; km200 mit Buderus GB172

Offline justme1968

  • Developer
  • Hero Member
  • ****
  • Beiträge: 19053
Antw:UDP Datagramme empfangen
« Antwort #27 am: 01 Februar 2019, 22:44:01 »
du darfst niemals die verwenden. damit beendest du dein programm.

einfach if( $conn ) ...

ja du irrst dich. wenn du ein socken auf machst lauschst du nur auf bestimmten adressen. das ist ohne angabe von LocalAddr normalerweise nur localhost und alle ip adressen die deine interfaces haben. da sind ohne das du dafür sorgst keine multicast adressen dabei. 239.255.255.250 ist eine multicast adresse.
FHEM5.4,DS1512+,2xCULv3,DS9490R,HMLAN,2xRasPi
CUL_HM:HM-LC-Bl1PBU-FM,HM-LC-Sw1PBU-FM,HM-SEC-MDIR,HM-SEC-RHS
HUEBridge,HUEDevice:LCT001,LLC001,LLC006,LWL001
OWDevice:DS1420,DS18B20,DS2406,DS2423
FS20:fs20as4,fs20bs,fs20di
AKCP:THS01,WS15
CUL_WS:S300TH

Offline herrmannj

  • Global Moderator
  • Hero Member
  • ****
  • Beiträge: 4940
Antw:UDP Datagramme empfangen
« Antwort #28 am: 01 Februar 2019, 22:55:25 »
Sailor,

nimm doch das script das ich oben gepostet habe und lass es einfach mal ohne fhem laufen. Dann kannst Du Dich Stück für Stück rantasten. Das "die" hat natürlich nichts in einem fhem Modul zu suchen.

Du postest immer im Wechsel Broadcast und Multicast Adressen. Was ist es denn nun ?  ;)

Noch als Idee: kann es sein dass der Port 6524 bei Dir schon geöffnet ist ?


smartVisu mit fronthem, einiges an HM, RFXTRX, Oregon, CUL, Homeeasy, ganz viele LED + Diverse

Offline Sailor

  • Developer
  • Hero Member
  • ****
  • Beiträge: 1387
  • und es werden immer mehr...
Antw:UDP Datagramme empfangen
« Antwort #29 am: 01 Februar 2019, 23:01:10 »
Hi justme
ja du irrst dich. wenn du ein socken auf machst lauschst du nur auf bestimmten adressen. das ist ohne angabe von LocalAddr normalerweise nur localhost und alle ip adressen die deine interfaces haben. da sind ohne das du dafür sorgst keine multicast adressen dabei. 239.255.255.250 ist eine multicast adresse.

Ok, war ein Versuch Wert, dann bleibt nur der Versuch ein Broadcast zu senden.
Zum Beispiel vom RasPi mittels socat - udp-sendto:255.255.255.255:6524,broadcast.
Zumindest taucht das im tshark als 192.168.178.RasPi → 255.255.255.255 UDP 43 45181 → 6524 Len=1 auf

Auch ohne "die" und ohne "eval" bleibt das Problem, dass die Socket-Verbindung $conn undefiniert bleibt.

DoorBird_OpenSocketConn - SocketConnection        : $VAR1 = undef;
******************************
Raspberry Pi mit DbLog, HomeMatic HMLAN
13x HM-SEC-SC; 11x HM-TC-IT-WM-W-EU; 13x HM-CC-RT-DN; 03x HM-Sec-SD; 01x HM-WDS10-TH-O; km200 mit Buderus GB172

 

decade-submarginal