Envoi socket variable binaire (declaration de type) [Résolu]

Arnosin - 13 août 2012 à 16:15 - Dernière réponse :  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,
Afficher la suite 

6 réponses

Répondre au sujet
cs_Jack 14010 Messages postés samedi 29 décembre 2001Date d'inscriptionModérateurStatut 28 août 2015 Dernière intervention - 13 août 2012 à 19:44
+3
Utile
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)
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de cs_Jack
cs_Jack 14010 Messages postés samedi 29 décembre 2001Date d'inscriptionModérateurStatut 28 août 2015 Dernière intervention - 13 août 2012 à 19:46
0
Utile
PS : J'ai inutilement compliqué l'entrée des valeurs en Hexa dans les 3 paramètres; ça ne sert à rien, pardon.
Commenter la réponse de cs_Jack
0
Utile
C'est génial, je ne connaissais pas, ça marche nickel !
Merci beaucoup !
Commenter la réponse de Arnosin
cs_Jack 14010 Messages postés samedi 29 décembre 2001Date d'inscriptionModérateurStatut 28 août 2015 Dernière intervention - 14 août 2012 à 17:24
0
Utile
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.
Commenter la réponse de cs_Jack
0
Utile
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,
Commenter la réponse de Arnosin
0
Utile
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,
Commenter la réponse de Arnosin

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.