TCPReceive Zahlen empfangen

  • Ich mal wieder..
    Schon den ganzen Mittag dran aber ich komm nicht klar..

    Ich habe eine DLLStruct names header

    [autoit]

    $struct_header = DllStructCreate("align 1;uint sequence;uint size;uint numwords")

    [/autoit]

    Nun lese ich von meinem Socket :

    [autoit]

    $buffer = TCPRecv($socket,DllStructGetSize($struct_header),1)

    [/autoit]

    In $buffer steht nun(als String..):
    0x010000402600000003000000
    Wobei dies so zu sehen ist:
    01000040 = Sequence
    26000000 = Size
    03000000 = Numwords

    Nun müsste ich diese "Hex-Werte" noch in die richtige reihenfolge bringen( aus 03000000 -> 00000003 machen) und dann aus dem String "00000003" eine dezimale Zahl machen und diese in meiner struktur abspeichern, damit ich nacher den dezimalen Wert 3 erhalte.

    Nun könnte ich per BinaryMid($buffer,1,4) die ersten 4 Byte herausfiltern ( 01000040 ) diese dann mit StringFunktionen nach 40000001 wandeln und darauf dann Number(40000001) anwenden und hätte dann eine dezimale Zahl, welche ich per DLLStructSetData($struct_Header,1,*zahl*) setzten könnte. Aber das wär ja ein Irre Aufwand für nur einen wert?

    Ich bin das ganze von c gewohnt und komme einfach nicht mit den Datentypen klar...
    In c würde das so aussehen


    Und er würde nun an die Adresse von h soviel schreiben wie der Header groß ist.
    Mit h.sequence hät ich jetzt gleich den int wert den ich empfangen habe.

    Ich hab den ganzen Mittag geschaut nach Besipielen, aber alle verschicken nur Strings und keine 4 byte Zahlen.

    Hoffe mir kann jemand helfen, da ich langsam echt verzweifel...

    Einmal editiert, zuletzt von Death (27. Dezember 2011 um 20:22)

  • Also wenn du die Werte so als String bekommst und das nicht ändern kannst, musst du das wohl so machen wie du schon beschrieben hast. Und wenn du es direkt als zahl senden willst, kannst du bei TCPSend die Daten ja auch schon als Binary senden.

    Gruss Shadowigor

  • Wie ich schon in der Shoutbox geschrieben habe, würde ich es so machen:

    [autoit]

    Func _TCPRecvStruct($socket, $struct, $timeout = -1)
    ; ProgAndy
    Local $size = DLLStructGetSize($struct)
    Local $data = Binary(""), $chunk
    Local $target = DLLStructCreate("byte[" & $size & "]", DLLStructGetPtr($struct))
    While $size
    Sleep(1)
    $chunk = TcpRecv($socket, $size, 1)
    If @error Then
    Return SetError(1, 0, False)
    ElseIf $chunk
    $size -= BinaryLen($chunk)
    $data &= $chunk
    EndIf
    WEnd
    DLLStructSetData($target, 1, $data)
    Return True
    EndFunc

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

    $struct_header = DllStructCreate("align 1;uint sequence;uint size;uint numwords")
    If _TCPRecvStruct($socket, $struct_header) Then MsgBox(0, "", DLLStructGetData($struct_header, 'size'))

    [/autoit]
  • Sorry ProgAndy ich habe es nun mit deiner Funktion überprüft und es geht(Nach ein paar Syntax fixes). Ich hatte zuvor dene Funktion als Vorbild genommen und dies gemacht :

    [autoit]


    $struct_header = DllStructCreate("align 1;uint sequence;uint size;uint numwords")

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

    $buffer = TCPRecv($socket,DllStructGetSize($struct_header),1)
    If @error Or $buffer = "" Then
    MsgBox(16,"Error","keine Daten empfangen....")
    Else

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

    Local $tmp_struct = DllStructCreate("align 1;char["&DllStructGetSize($struct_header)&"];",DllStructGetPtr($struct_header))
    DllStructSetData($tmp_struct,1,$buffer)

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

    MsgBox(0, "", DLLStructGetData($struct_header, 'size'))
    EndIf

    [/autoit]


    Allerdings kommt so mist raus und so dachte ich deine iwrd auch nicht funktionieren, da ich doch im Prinzip dasselbe mache wie du?

    Kannst du mir vll. den Unterschied zeigen?

  • TCPRecv garantiert dir nicht, dass du DllStructGetSize($struct_header) Bytes an Daten erhälst. Damit legst du nur das maximale Limit fest. Du musst also zuerst warten, bis du alle Daten empfangen hast, die du brauchst (Die While-Schleife bei mir)
    Wenn du mit bytes arbeitest, dann verwende auch immer byte[] statt char[], da char in AutoIt an Nullbytes abschneiden könnte.

  • Also wenn ich $buffer ausgebe stehen 12byte drin(richtig), ich weiß das es nicht sicher ist das tcprecv 12byte empfangen hat, aber hat es in diesem fall getan

    €dit: ahhhhhhhhhhh wenn ich byte statt char nehme geht alles ich dank dir ... :thumbup: