Envoi socket variable binaire (declaration de type)

Résolu
Arnosin - 13 août 2012 à 16:15
 Arnosin - 17 août 2012 à 10:38
Bonjour,

Je voudrais envoyer des messages à un ordinateur par socket.
Je l'ai déjà fais avec du texte (ws.senddata "toto"), mais là ce n'est plus du texte mais des messages types contenant plusieurs variables. Exemple pour le message 6001 :

Public Type ty_6001
header As ty_Header
Pad As Byte
DataChkS As Long
End Type
public M6001 as ty_6001

public sub SendMessage()
ws.SendData M6001
end sub

D'après la doc il faut passer par un tableau d'octets pour envoyer du binaire avec senddata, mais comment convertir mon message "M6001" en tableau de bytes???
Est-ce que quelqu'un peut m'aider?
Merci d'avance,

6 réponses

cs_Jack Messages postés 14006 Date d'inscription samedi 29 décembre 2001 Statut Modérateur Dernière intervention 28 août 2015 79
13 août 2012 à 19:44
Salut

Oui, cela fonctionnera à condition que les variables utilisées dans ton type soient de longueur définie par le type.
String, par exemple, ne pourrait pas fonctionner.
Je te dis ça car on ne connait pas la définition de ty_Header, ton premier 'paramètre'.

Pour transformer un Long en un tableau de Byte ... et reciproquement :
Déclarations :
Option Explicit
Private Type InputStructure
    monLong1    As Long     ' 4 octets/bytes
    monByte1    As Byte     ' 1 octets/bytes
    monLong2    As Long     ' 4 octets/bytes
End Type
Private oInputDatas     As InputStructure
Private aOutputBytes()  As Byte
Private Declare Sub CopyMemory Lib "kernel32" _
                    Alias "RtlMoveMemory" ( _
                    pDst As Any, _
                    pSrc As Any, _
                    ByVal ByteLen As Long)

Structure -> tableau de bytes :
    With oInputDatas
        .monLong1 = &H499602D2  ' 1234567890 en décimal
        .monByte1 = &H6F        ' 111 en décimal
        .monLong2 = &H42E576F7  ' 1122334455 en décimal
    End With
    ' Prépare un tableau de même longueur (qui commence à l'index 0)
    ReDim aOutputBytes(LenB(oInputDatas) - 1)
    ' Transfert des données
    Call CopyMemory(aOutputBytes(0), _
                    ByVal VarPtr(oInputDatas), _
                    LenB(oInputDatas))

Tableau de Bytes -> Structure :
    If UBound(aOutputBytes) <= 0 Then Exit Sub
    Dim oRecup  As InputStructure
    ' Transfert des données
    Call CopyMemory(oRecup, _
                    ByVal VarPtr(aOutputBytes(0)), _
                    UBound(aOutputBytes) + 1)
    ' Vérif
    With oRecup
        Debug.Print "Premier Long", .monLong1
        Debug.Print "Premier Byte", .monByte1
        Debug.Print "Second Long", .monLong2
    End With

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

Le savoir est la seule matière qui s'accroit quand on la partage (Socrate)
3
cs_Jack Messages postés 14006 Date d'inscription samedi 29 décembre 2001 Statut Modérateur Dernière intervention 28 août 2015 79
13 août 2012 à 19:46
PS : J'ai inutilement compliqué l'entrée des valeurs en Hexa dans les 3 paramètres; ça ne sert à rien, pardon.
0
C'est génial, je ne connaissais pas, ça marche nickel !
Merci beaucoup !
0
cs_Jack Messages postés 14006 Date d'inscription samedi 29 décembre 2001 Statut Modérateur Dernière intervention 28 août 2015 79
14 août 2012 à 17:24
De rien.

Petite suggestion : L'API aliassée "CopyMemory" peut donner des résultats bizarres, voire planter sauvagement ton programme (sans gestion d'erreur possible).
Je te conseille donc TRES
fortement de toujours enregistrer ton projet avant de faire un Run.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Merci pour le conseil !
j'ai eu quelques plantages sauvages effectivement, mais il y avait un problème dans la taille de la structure à convertir.
J'espère qu'il n'y aura pas de plantage pas la suite, quand le code sera définitif...
En tout cas merci pour ton aide,
0
Bonjour,
Je viens de m'apercevoir d'un petit soucis avec cette fonction pour l'utilisation que je veux en faire. En effet, il me créé un tableau de bytes correspondant à ce qui a été chargé en mémoire. Le problème est que le tableau est plus long que la somme de la taille de mes variables :
dans mon cas :
len(M6002) -> 5
lenB(M6002) -> 8

Public ty_6002
    Pad As Byte
    DataChkS As Long
End Type
Public M6002 As ty_6002
Private aOutputBytes()  As Byte
Private Declare Sub CopyMemory Lib "kernel32" _
                    Alias "RtlMoveMemory" ( _
                    pDst As Any, _
                    pSrc As Any, _
                    ByVal ByteLen As Long)

Private Sub Sendm6002()
M6002.Pad = &HAA
M6002.DataChkS = &HF0F0F0F0

ReDim aOutputBytes(LenB(M6002) - 1)
Call CopyMemory(aOutputBytes(0), ByVal VarPtr(M6002), LenB(M6002))
For i = 0 To UBound(aOutputBytes)
    Mytxt = Mytxt + "Byte(" + CStr(i + 1) + ")" + _
       vbTab + Hex(SendMessge(i)) + vbCrLf
Next i
WS.SendData aOutputBytes
End Sub


Le tableau envoyé est celui-ci :
Byte(1) AA
Byte(2) 0
Byte(3) 0
Byte(4) 0
Byte(5) F0
Byte(6) F0
Byte(7) F0
Byte(8) F0

alors que je souhaite envoyer :
Byte(1) AA
Byte(2) F0
Byte(3) F0
Byte(4) F0
Byte(5) F0

Comment est ce que je peux créer un tableau de bytes sans ces octets parasites (pour moi)? Est-ce qu'il faut changer l'allias? Est-ce qu'une autre fonction existe?

Merci d'avance pour vos réponses,
0
Rejoignez-nous