Broadcast Adresse für alle Fälle

  • Hallo,

    ich habe einen Script programmiert, welchen einen UDP Server enhält. Einen weiteren der einen UDP Client enthält. Der UDP Server wird auf 30 Rechnern auf @IPAdress1, Port 555 ausgeführt. Die Server haben IP-Adressen von 192.168.0.20-50. Der Client hat die IP 192.168.0.1. Das Subnetz ist 255.255.255.0. Nun sende ich ein Nachricht per UDP vom Client ins Netz an: 192.168.0.255. Alle Server empfangen auch diese Nachricht. Nun habe ich den Script z.B. an einen Freund gegeben. Dort sind die Server im Bereich: 10.7.1.50-10.7.1.80. Der Client hat die IP 10.7.1.17. Das Subnetz ist 255.255.0.0. Dort geht natürlich die Broadcast Adresse 192.168.0.255 nicht. Da ich die Broadcast Adresse nicht abfragen möchte vom Benutzer, suche ich eine Broadcast Adresse die überall geht. Ich habe bereits die Adresse 255.255.255.255 und 244.0.0.0 versucht. Beide gehen nicht.

    [autoit]

    UDPStartUp()

    [/autoit][autoit][/autoit][autoit]

    $socket = UDPBind("192.168.0.21", "555")

    [/autoit][autoit][/autoit][autoit]

    $socket2 = UDPOpen("255.255.255.255", "555") ; klar mit 192.168.0.255 geht es hier <<
    UDPSend($socket2, "hallo")

    [/autoit][autoit][/autoit][autoit]

    $data = UDPRecv($socket, 50)
    MsgBox(0, "UDP DATA", $data, 1)

    [/autoit][autoit][/autoit][autoit]

    UDPCloseSocket($socket)
    UDPCloseSocket($socket2)

    [/autoit][autoit][/autoit][autoit]

    UDPShutdown()

    [/autoit]

    Hat jemand einen Tipp?

    Viele Grüße
    Gespenst

    Einmal editiert, zuletzt von Gespenst (1. Juni 2008 um 16:08)

  • Hallo.

    Also Du solltest dich mit IP's und Subnetting etwas mehr auseinander setzen. Hier empfehle ich:
    - http://de.wikipedia.org/wiki/IP-Adresse
    - http://de.wikipedia.org/wiki/Subnetting

    Ich selber habe über diese Seiten während meines MCP-Lehrgangs sogar das Subnetting und das ganze was damit zu tun hat wesentlich besser verstanden.

    Wenn Du das durch hast, sollten Deine Fragen auch beantwortet sein und dann nur noch die Umsetzung evtl. ein Problem darstellen.

    Gruß, Crazy-A.

    Lieben Gruß,
    Alina

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Geheime Information: ;)
    OuBVU5ebLhHu5QvlnAyQB4A7SzBrvWulwL7RLl2BdH5tI6sIYspeMKeXMSXl

    • Offizieller Beitrag

    Hallo,

    ich hatte da vor einiger Zeit mal eine Funktion für geschrieben!

    Spoiler anzeigen
    [autoit]

    ; ==========================================================================================================================
    ; Name: GetNetInfo
    ; Description: Ermittelt aus IP-Adresse/Netzadresse und Subnetmaske einige Netzinformationen
    ;
    ; Parameter(s): $szIP = IP-Adresse/Netzadresse
    ; $szSN = Subnetmaske
    ; $cInfo = Gibt an welche Information zurückgegeben werden soll
    ; -1 = alle als Array (Standard)
    ; 0 = Netzadresse als String
    ; 1 = Broadcastadresse als String
    ; 2 = kleinste Hostadresse als String
    ; 3 = größte Hostadresse als String
    ;
    ; Requirement(s): keine
    ; Return Value(s): Array oder String mit gewünschter Information
    ;
    ; Author(s): bernd670
    ; ==========================================================================================================================
    Func GetNetInfo($szIP, $szSN, $cInfo=-1)
    Local $aszIP = StringSplit($szIP, "."), $dwIP
    Local $aszSN = StringSplit($szSN, "."), $dwSN
    Local $dwBC, $dwNA, $dwHostMin, $dwHostMax
    Local $aszNI[4]

    $dwIP = BitOR(BitShift(BitOR(BitShift(BitOR(BitShift($aszIP[1],-8),$aszIP[2]),-8),$aszIP[3]),-8),$aszIP[4])
    $dwSN = BitOR(BitShift(BitOR(BitShift(BitOR(BitShift($aszSN[1],-8),$aszSN[2]),-8),$aszSN[3]),-8),$aszSN[4])
    $dwBC = BitOR($dwIP, BitXOR($dwSN,0xFFFFFFFF))
    $dwNA = BitAND($dwIP, $dwSN)
    $dwHostMin = BitAND($dwBC,$dwSN+1)
    $dwHostMax = BitAND($dwBC,0xFFFFFFFE)

    $aszNI[0] = BitAND(BitShift($dwNA,24),255) & "." & BitAND(BitShift($dwNA,16),255) & "." & BitAND(BitShift($dwNA,8),255) & "." & BitAND($dwNA,255)
    $aszNI[1] = BitAND(BitShift($dwBC,24),255) & "." & BitAND(BitShift($dwBC,16),255) & "." & BitAND(BitShift($dwBC,8),255) & "." & BitAND($dwBC,255)
    $aszNI[2] = BitAND(BitShift($dwHostMin,24),255) & "." & BitAND(BitShift($dwHostMin,16),255) & "." & BitAND(BitShift($dwHostMin,8),255) & "." & BitAND($dwHostMin,255)
    $aszNI[3] = BitAND(BitShift($dwHostMax,24),255) & "." & BitAND(BitShift($dwHostMax,16),255) & "." & BitAND(BitShift($dwHostMax,8),255) & "." & BitAND($dwHostMax,255)

    [/autoit] [autoit][/autoit] [autoit]

    If $cInfo = -1 Then
    Return $aszNI
    Else
    Return $aszNI[$cInfo]
    EndIf
    EndFunc ;==>GetNetInfo

    [/autoit]
  • Hallo Zusammen,

    ich hab das gleiche Problem wie der User Gespenst. Ein UDPopen an die 255.255.255.255 funktioniert problemlos, es wird kein @error zurückgeliefert. Man bekommt sogar nen gültigen Socket, trotzdem wird nichts gesendet. ich hab mal mit Wireshark mitgetracet, da passiert rein garnichts. :( In meinen Augen ist das ein Bug. Und ja, mein Programm funktioniert, wenn ich die LAN-spezifische Prodcast-Adresse benutze, aber das geht in meinem speziellen Fall nicht. Ich bin auf 255.255.255.255 angewiesen.

    Ist das ein Bug oder kann man das sonst irgendwie lösen?

    Besten Dank und happy computing!
    R@iner

    PS: In dem ersten Link von Crazy-A. steht geschrieben, daß 255.255.255.255 eine gültige Broadcaast-Adresse ist.

    Zitat

    Die spezielle Adresse 255.255.255.255 kann neben der höchsten Geräteadresse im Netz ebenfalls als Broadcastadresse verwendet werden. Dadurch ist das Versenden von Broadcasts ohne Kenntnis weiterer Netzwerkparameter möglich. Dies ist für Protokolle wie BOOTP und DHCP wichtig.

  • Hallo skyteddy,

    vielleicht liegts ja daran

    Zitat

    Es werden verschiedene Formen von IP-Broadcasts unterschieden:

    Limited Broadcast
    Als Ziel wird die IP-Adresse 255.255.255.255 angegeben. Dieses Ziel liegt immer im eigenen Netz und wird direkt in einen Ethernet-Broadcast umgesetzt. Ein limited broadcast wird von einem Router nicht weitergeleitet

    Auszug aus Wikipedia Bbroadcast, wenn nicht nimm mal die Funktion von Bernd zur Hand (GUI fehlt) und teste damit ob es für dein Netzwerk eine gültige Adresse ist,

    mfg (Auto)Bert

  • Hallo Autobert,

    dank Dir für die schnelle Antwort, aber die Broadcast-Adresse ermitteln ist nicht das Thema. Ich hab hier ein Device was nicht reagiert. Der Broadcast (an die "normale" Broadcast-Adresse) wird auch abgeschickt, das sehe ich mit Wireshark, trotzdem reagiert das Device nicht. Benutze ich das Mammut-Programm zu dem Device, was die Funktionalität bietet, dann stoppt das Device.

    Wenn ich jetzt mit Wireshark die Unterschiede anschaue, dann ist als einziges die Broadcast-Adresse unterschiedlich. Der Rest meines Pakets ist identisch, Port, Data. Das paßt alles. Auch vom Timing her ist AutoIt nicht zu langsam. Es stimmt in meinen Augen lediglich die Zieladresse nicht. Ich müßte nen Broadcast an 255.255.255.255 schicken und wie schon gesagt, AutoIt sendet nichts, aber rein garnichts, bringt aber auch keinen Fehler. :(

    Happy computing!
    R@iner

    Einmal editiert, zuletzt von skyteddy (27. April 2009 um 01:47)

  • Wenn man im Client die Winsock-Funktionen direkt verwendet, funktioniert es:

    Client
    [autoit]


    UDPStartup()
    Global $WS = DllOpen("Ws2_32.dll")

    [/autoit] [autoit][/autoit] [autoit]

    Global Const $AF_INET = 2
    Global Const $SOCK_DGRAM = 2

    [/autoit] [autoit][/autoit] [autoit]

    Global Const $sockaddr_in = _
    "short family;" & _
    "ushort port;" & _
    "ulong addr;" & _
    "char zero[8];"

    [/autoit] [autoit][/autoit] [autoit]

    Global Const $SOL_SOCKET = 0xFFFF
    Global Const $SO_BROADCAST = 0x20

    [/autoit] [autoit][/autoit] [autoit]

    ; socket erstellen
    $SOCKET = DllCall($WS, "uint", "socket", "int", $AF_INET, "int", $SOCK_DGRAM, "int", 0)
    If Not @error Then $SOCKET = $SOCKET[0]

    [/autoit] [autoit][/autoit] [autoit]

    ; broadcast erlauben
    DllCall($WS, "int", "setsockopt", "uint", $SOCKET, "int", $SOL_SOCKET, "int", $SO_BROADCAST, "int*", 1 , "int", 4)

    [/autoit] [autoit][/autoit] [autoit]

    ; Ziel Adresse und Port
    $remote = DllStructCreate($sockaddr_in)
    DllStructSetData($remote, "family", $AF_INET)
    DllStructSetData($remote, "port", _htons(65532))
    DllStructSetData($remote, "addr", _inet_addr("255.255.255.255"))

    [/autoit] [autoit][/autoit] [autoit]

    $to = DllStructGetPtr($remote)
    $toLen = DllStructGetSize($remote)

    [/autoit] [autoit][/autoit] [autoit]

    ; Daten zum senden
    $Buffer = DllStructCreate("char[255]")
    DllStructSetData($Buffer,1,"Test string 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ sdgf slhgf lahg rkahgr kjagh rk gh fgh fgh fgh fgh fghfjah rkjfha rkhge alirzqlw5zhöoa blvig6galizhkljahl etrjlk lhkgtl akhgtlarehgkjfht hagr lahsvbf lyshgdf öahdf asghvf lasf ei5uwo fvrs. fksfv dknf scdf sjgdfds")
    $pBuffer = DllStructGetPtr($Buffer)
    $BufLen = DllStructGetSize($Buffer)
    $Flags = 0

    [/autoit] [autoit][/autoit] [autoit]

    ; senden
    $SENT = DllCall($WS, "int", "sendto", "uint", $SOCKET, "ptr", $pBuffer, "int", $BufLen, "int", $Flags, "ptr", $to, "int", $toLen)
    MsgBox(0, 'UDP broadcast', $SENT[0] & " Bytes gesendet")

    [/autoit] [autoit][/autoit] [autoit]

    UDPShutdown()
    DllClose($WS)

    [/autoit] [autoit][/autoit] [autoit]

    Func _htons($Short)
    ; Prog@ndy
    Local $aResult = DllCall($WS, "ushort", "htons", "ushort", $Short)
    If @error Then Return SetError(1,0,0)
    Return $aResult[0]
    EndFunc
    Func _inet_addr($IP)
    ; Prog@ndy
    Local $aResult = DllCall($WS, "ulong", "inet_addr", "str", $IP)
    If @error Then Return SetError(1,0,0)
    Return $aResult[0]
    EndFunc

    [/autoit]
    Server
    [autoit]

    ;;This is the UDP Server
    ;;Start this first

    [/autoit] [autoit][/autoit] [autoit]

    ; Start The UDP Services
    ;==============================================
    UDPStartup()

    [/autoit] [autoit][/autoit] [autoit]

    ; Bind to a SOCKET
    ;==============================================
    $socket = UDPBind("", 65532)
    If @error <> 0 Then Exit

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    $data = UDPRecv($socket, 1024)
    If $data <> "" Then
    MsgBox(0, "UDP DATA", $data)
    EndIf
    sleep(100)
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func OnAutoItExit()
    UDPCloseSocket($socket)
    UDPShutdown()
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit]
  • Hallo Andy,

    super, spitze! Du bist ne Wucht! Damit ging es auf Anhieb! Vielen herzlichen Dank dafür!

    Allerdings hab ich jetzt einige Fragen. Ich hab zwar schon in der MSDN-Library nach "Ws2_32.dll" gesucht, finde ~ 3.000 Einträge, aber nicht den, wo sie den Call ansich beschrieben und mit was man was füttern muß. Hast Du für mich bitte, danke den Links zur Hand?

    $AF_INET, $SOCK_DGRAM, $SOL_SOCKET und $SO_BROADCAST sind wahrscheinlich fix und wird vom ws2_32.dll so gebraucht, oder? Ist das Zufall, daß $SOL_SOCKET = 0xFFFF= 65532 und somit gleich deinem verwendeten Port ist? Ich hab nämlich beim Port was anderes benutzt und ging problemlos.

    Der Router stoppt jetzt seinen Bootvorgang und ich bekomme jetzt via UDPRecv 16 Byte vom Router zurück, also z.B. "0x00011a1b1122334400022a2b55667788". Es ist mir klar, daß das Hex ist, daher sind es 34 Zeichen. Abzüglich des "0x" sind es noch 32. Wie bringe ich das jetzt am einfachsten in die nachfolgende Structur?

    Global Const $MyStruct = _ ; 16 Byte in der Summe
    "short Sequenz1;" & _ ; 2 Byte
    "byte Part1A;" & _ ; 1 Byte
    "byte Part1B;" & _ ; 1 Byte
    "uint Address1;" & _ ; 4 Byte
    "short Sequenz2;" & _ ; 2 Byte
    "byte Part2A;" & _ ; 1 Byte
    "byte Part2B;" & _ ; 1 Byte
    "uint Address2;" ; 4 Byte

    Muß ich den "0x00011a1b1122334400022a2b55667788" selber zerlegen und die Structur auffüllen, oder gibt es da nen eleganten Weg?

    Besten Dank und ein schönes Wochenende!
    R@iner

  • Du kannst das über DLLstructs machen ;)

    [autoit]

    $Struct = DllStructCreate($MyStruct)

    [/autoit][autoit][/autoit][autoit]

    $BinStruct = DllStructCreate("byte[" & DllStructGetSize($Struct) & "]", DllStructGetPtr($Struct) )

    [/autoit][autoit][/autoit][autoit]

    DllStructSetData($BinStruct, 1, $Binary)

    [/autoit]


    Jetzt kannst du alles aus der $Struct auslesen.
    oder du verwendest zum empfangen auch die Funktionen direkt aus der Ws2_32 und gibst dort als Buffer die DLLStruct an.
    und die Funktionen gibt es hier: http://msdn.microsoft.com/en-us/library/…28VS.85%29.aspx

  • Hallo Andy,

    ja, so hatte ich es auch gemacht, ging gestern Abend aber nicht. Keine Ahnung warum. :(

    Heute hab ich es nochmal frisch gemacht, und schon klappt es auf Anhieb. Allerdings habe ich ein Verständnisproblem mit dem Befüllen der Bytes. Wenn Du Dir die Ausgabe meines Tests hier mal anschaust, dann werden die Bytes gedreht und ich weiß nicht wirklich warum. Hast Du ne Ahnung warum das so ist.

    Also speziell meine ich den Unterschied zwischen dem Befüllen einer kompletten Structur in einem String und meiner TestStructur mit 2 einzelnen SetData. Da sind die Bytes gedreht. ?(

    Spoiler anzeigen
    [autoit]


    Opt("MustDeclareVars", 1)

    [/autoit] [autoit][/autoit] [autoit]

    ; Struktur definieren
    Global Const $MyStruct = _ ; 16 Byte in der Summe
    "short Sequenz1;" & _ ; 2 Byte
    "byte Part1A;" & _ ; 1 Byte
    "byte Part1B;" & _ ; 1 Byte
    "uint Address1;" & _ ; 4 Byte
    "short Sequenz2;" & _ ; 2 Byte
    "byte Part2A;" & _ ; 1 Byte
    "byte Part2B;" & _; 1 Byte
    "uint Address2;" ; 4 Byte

    [/autoit] [autoit][/autoit] [autoit]

    ; Angenommene Daten die vom Router zurückkommen
    ; In Hex: 00 01, 1a, 1b, 11 22 33 44, 00 02, 2a, 2b, 55 66 77 88
    Local $BinaryDataFromUDP = "0x00011a1b1122334400022a2b55667788" ; 16 Byte
    Ausgabe("$BinaryDataFromUDP", $BinaryDataFromUDP) ; Testausgabe

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    #Region --- UDP-Daten ---
    ; Datensatz (als Struktur)
    Global $UDPStruct = DllStructCreate($MyStruct)

    [/autoit] [autoit][/autoit] [autoit]

    ; Datensatz (als Byte-Ansammlung)
    Global $UDPBinStruct = DllStructCreate("byte[" & DllStructGetSize($UDPStruct) & "]", DllStructGetPtr($UDPStruct))

    [/autoit] [autoit][/autoit] [autoit]

    ; Daten setzen
    DllStructSetData($UDPBinStruct, 1, $BinaryDataFromUDP)

    [/autoit] [autoit][/autoit] [autoit]

    ; Ausgabe in Dezimal
    StructAusgabeDec("$UDPStruct", $UDPStruct)
    ; Ausgabe in Hex
    StructAusgabeHex("$UDPStruct", $UDPStruct)
    #EndRegion --- UDP-Daten ---

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    #Region --- Meine Test-Daten ---
    ; Datensatz (als Struktur)
    Global $TestStruct = DllStructCreate($MyStruct)

    [/autoit] [autoit][/autoit] [autoit]

    ; Testweise etwas setzen
    DllStructSetData($TestStruct, "Sequenz1", "0x0001") ; 2 Byte, wie oben in $BinaryDataFromUDP
    DllStructSetData($TestStruct, "Address1", "0x11223344") ; 4 Byte, wie oben in $BinaryDataFromUDP

    [/autoit] [autoit][/autoit] [autoit]

    ; Datensatz (als Byte-Ansammlung)
    Global $TestBinStruct = DllStructCreate("byte[" & DllStructGetSize($TestStruct) & "]", DllStructGetPtr($TestStruct))
    Ausgabe("$TestBinStruct", DllStructGetData($TestBinStruct, 1)) ; Testausgabe

    [/autoit] [autoit][/autoit] [autoit]

    ; Ausgabe in Dezimal
    StructAusgabeDec("$TestStruct", $TestStruct)
    ; Ausgabe in Hex
    StructAusgabeHex("$TestStruct", $TestStruct)
    #EndRegion --- Meine Test-Daten ---

    [/autoit] [autoit][/autoit] [autoit]

    Ausgabe("", @CRLF & @CRLF)
    Exit

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    #Region --- Funktionen ---

    [/autoit] [autoit][/autoit] [autoit]

    ; Funktion, die MyStruct in Dec ausgibt
    Func StructAusgabeDec($name, $struct)
    Local $msg = "Struct Size: " & DllStructGetSize($struct) & @CRLF & _
    "Struct pointer: " & DllStructGetPtr($struct) & @CRLF & _
    "Data:" & @CRLF & _
    DllStructGetData($struct, "Sequenz1") & @CRLF & _
    DllStructGetData($struct, "Part1A") & @CRLF & _
    DllStructGetData($struct, "Part1B") & @CRLF & _
    DllStructGetData($struct, "Address1") & @CRLF & _
    DllStructGetData($struct, "Sequenz2") & @CRLF & _
    DllStructGetData($struct, "Part2A") & @CRLF & _
    DllStructGetData($struct, "Part2B") & @CRLF & _
    DllStructGetData($struct, "Address2")

    [/autoit] [autoit][/autoit] [autoit]

    Ausgabe('Struct "' & $name & '" in Dec', $msg)
    EndFunc ;==>StructAusgabeDec

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ; Funktion, die MyStruct in Hex ausgibt
    Func StructAusgabeHex($name, $struct)
    Local $msg = "Struct Size: " & DllStructGetSize($struct) & @CRLF & _
    "Struct pointer: " & DllStructGetPtr($struct) & @CRLF & _
    "Data:" & @CRLF & _
    Hex(DllStructGetData($struct, "Sequenz1")) & @CRLF & _ ; LowByte/HighByte? -> Byte sind gedreht
    Hex(DllStructGetData($struct, "Part1A")) & @CRLF & _
    Hex(DllStructGetData($struct, "Part1B")) & @CRLF & _
    Hex(DllStructGetData($struct, "Address1")) & @CRLF & _ ; Little Endian? -> Reihenfolge rückwärts
    Hex(DllStructGetData($struct, "Sequenz2")) & @CRLF & _
    Hex(DllStructGetData($struct, "Part2A")) & @CRLF & _
    Hex(DllStructGetData($struct, "Part2B")) & @CRLF & _
    Hex(DllStructGetData($struct, "Address2"))

    [/autoit] [autoit][/autoit] [autoit]

    Ausgabe('Struct "' & $name & '" in Hex', $msg)
    EndFunc ;==>StructAusgabeHex

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ; Funktion, die einfach eine Ausgabe in die Console macht (mit Trennlinie und Überschrift)
    Func Ausgabe($was = "", $Inhalt = "")
    ; Trennlinie
    ConsoleWrite("_______________________________________________________________________________" & @CRLF)
    ; Was
    If $was <> "" Then ConsoleWrite("---- " & $was & " -----" & @CRLF)
    ; Inhalt
    ConsoleWrite($Inhalt & @CRLF)
    EndFunc ;==>Ausgabe

    [/autoit] [autoit][/autoit] [autoit]

    #EndRegion --- Funktionen ---

    [/autoit]

    Danke und ein schönes Wochenende!
    R@iner

    PS: Hätte ich besser einen neuen Thread aufmachen sollen?