Problème byte, string

retaks666 Messages postés 286 Date d'inscription jeudi 2 janvier 2003 Statut Membre Dernière intervention 16 juillet 2007 - 22 déc. 2004 à 23:32
cs_Jack Messages postés 14006 Date d'inscription samedi 29 décembre 2001 Statut Modérateur Dernière intervention 28 août 2015 - 24 déc. 2004 à 03:39
Bonjour, j'ai un problème:
J'ai une application qui recoie des donnée de type byte par un winsock, et je voudrait convertir une partie de ces donnée en string, mais pas l'autre.
Une partie de ces données corresponde a la position octale d'un fichier, et l'autre partie au données a écrire a cette position, seulement, si je transtype toute la chaine, certaines données bytes vont être perdue, car elles ne peuvent pas être transtypées.
J'envoi a mon appli de cette façon:
positionoctale & "#" & nombre de bytes & "#" & données bytes
je cherche a récuperer la position octale et le nombre de bytes

J'ai fait comme ça mais ça marche pas :'(

For i = 1 To UBound(bufftmp)
Dim diese As Boolean
diese = False
If Chr$(bufftmp(i)) = "#" Then
    If diese = False Then 'pour qu'on prenne en compte le deuxième dièse
    diese = True
    Else
    Dim buffer()
    ReDim buffer(UBound(bufftmp) - i)
        For j = 0 To UBound(bufftmp) - i
        buffer(j) = bufftmp(i + j)
        Next j
    ReDim bufftmp(UBound(buffer))
    'bufftmp() = buffer()
    End If
End If
 
Next i

13 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
23 déc. 2004 à 03:21
lol
Pour ceux qui n'auraient pas suivis, ce post fait suite au roman 356182 de cet autre Post
Bref, comme je te le disais, il suffit d'isoler les deux premiers paramètres qui sont séparés par des #.
Pour cela, je t'avais suggéré la fonction Split que tu n'as pas mis en application et du coup, tu t'es perdu.
N'utilise pas des mots comme 'octal' sans en connaitre le sens : Les données ne sont pas transmises en octal, car cela voudrait dire que les chiffres sont exprimés en base 8, ce qui n'est pas le cas. La base est la même entre Octet et Octal : le chiffre 8 :Octet 8 bits, et Octal chiffres en base 8
Il n'y a pas d'autre lien.
Winsock ne renvoi QUE des caractères.

Je vais pas te faire ton code, je vais juste répéter.
Tu reçois cette trame :
Trame = "Données" & "#" & CStr(Position) & "#" & CStr(LongueurDesDonnées) & "#" & 'les octets du fichier'
Pour décomposer la trame :
Dim Tablo() As String
Tablo = Split(Trame, "#")

Position = CLng(Tablo(0))
LongueurDonnées = CLng(Tablo(1))
( CLng ne fait que convertir une chaine en chiffre)
Les octets du fichier qui suivent peuvent être composés de tout type de caractères, y compris des # : On ne peut donc pas dire que DonnéesFichier = Tablo(2)

Là, il faut utiliser les manipulations de chaines :
Les données commencent après le deuxième # :
Détection du deuxième # :
Tu connais la longueur de chaque donnée qui compose la trame :
"Données" = 7
# = 1
Position = Len(Cstr(Position))
# = 1
LongeurDonnées = Len(Cstr(LongueurDonnées))
# = 1
La position de début des données du fichier se trouve donc à :
DébutDonnées = 7 + 1 + Len(Cstr(Position)) + 1 Len(Cstr(LongueurDonnées)) + 1 + 1
Le dernier '+1' est là pour indiquer le caractère qui suit le dernier #

Puisque tu connais la longueur des données, les données reçues peuvent être isolées comme ceci :
Données = Mid(Trame, DébutDonnées, LongeurDonnées)

Vala
Jack
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)
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
23 déc. 2004 à 03:48
Attention :
Comme je l'ai dit dans un autre post, la quantité de données reçue dans un WinSock dépend : De la charge du réseau, de la charge de la machine et de la longueur des données.
Il se peut donc que, si tes données sont trop longues, tu reçoives le début de la trame, mais que toutes les données du fichier ne soient pas toutes derrière !

Calcul de la longueur de la trame complète nécessaire :
LongueurTrame = 7 + 1 + Len(Cstr(Position)) + 1 Len(Cstr(LongueurDonnées)) + 1 + LongueurDonnées

Faire le Test suivant :
If Len(Trame) < LongueurTrame Then
c'est que toutes les données de ton fichier ne sont pas encore toutes arrivées.

Je te donne en deux la méthode :
Le DataArrival va se déclencher une première fois avec le début de la trame.
Tu fais la décomposition des entêtes comme expliqué au dessus, puis il faut faire LeTest :
Si ce test dit que toutes les données ne sont pas encore arrivées, il faut donc ressortir sans rien faire, si ce n'est mémoriser les données quelque part :

Dans DataArrival, dimensionne une variable comme ceci :
Static Mémo As String
C'est comme un Dim, mais là, la vriable gardera la valeur que tu auras laissé au cycle précédent.
Quand tu reçois les données, stocke les tout de suite à la mémoire :
WinSock.GetData Trame, , bytesTotal
Mémo = Mémo & Trame

Ensuite, tu fais le découpage avec le Slip (comme indiqué au dessus), mais en utilisant Mémo (à la place de Trame)

Ensuite, fais le test :
If Len(Mémo) < LongueurTrame Then
' On n'a pas reçu toutes les données
' On ressort sans rien faire, les données sont sauvées
Exit Sub
Else
' Traite les données
Données = Mid(Trame, DébutDonnées, LongeurDonnées)
' Ecrit les dans ton fichier à la position donnée par ... Position
...
' Et avant de sortir, il faut penser à vider la mémoire
' sinon, tu les traiteras à nouveau au prochain cycle.
' Au lieu de vider la mémoire, on va supprimer le début
' de la mémoire de la longueur qui va bien :
Mémo = Mid(Mémo, LongueurTrame + 1)  ' *
End If


(*) Ici, la fonction Mid est utilisée en oubliant le dernier terme, la longueur : Si on ne met pas de longueur (3e terme), VB prend tout ce qui suit jusqu'à la fin, c'est ce qui nous intéresse ici.
Le '+1' est pour dire de commencer au caractère qui suit notre trame.

Vala
Tout ça va te sembler lourd, mais c'est une bonne méthode pour ne pas perdre de données !
Analyse bien et tu verras que c'est simple.

Jack
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)
0
Gobillot Messages postés 3140 Date d'inscription vendredi 14 mai 2004 Statut Membre Dernière intervention 11 mars 2019 34
23 déc. 2004 à 04:13
tiens une nouvelle fonction que je connaissais pas ...!

t'es drôle jack

Daniel
0
retaks666 Messages postés 286 Date d'inscription jeudi 2 janvier 2003 Statut Membre Dernière intervention 16 juillet 2007
23 déc. 2004 à 13:01
Merci jack, note, j'avais bien fait ta méthode avec split, mais mon problème réel ne vient pas de la, c'est que je n'arrives pas a concaténer des donnée string avec des octets, le code suivant me renvoi une erreur type incompatible:
trame = CStr(position) & "#" & UBound(Buffer) & "#" & Buffer()
Il faut donc que je transtype buffer en string, mais le problème est que buffer peut contenir des données ne correspondant pas a des caractères, pour les fichiers texte aucun problème, mais pour les images ou les zip, le fichier a la fin n'est pas conforme.... Je comptais envoyer tout en bytes et faire le tri a la réception. mais si tu me dit que winsock ne gère que les caractères je sais pas comment je vais faire :s
Sinon, pour ce qui est de la gestion d'arrivée, j'ai pas trop besoin de ça, puis que mon programme envoi une réponse lors de la réception d'un packet, qui déclenche l'envoi de la suite des données, cela fait perdre un peu de temps, mais c'est fiable.
0

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

Posez votre question
Gobillot Messages postés 3140 Date d'inscription vendredi 14 mai 2004 Statut Membre Dernière intervention 11 mars 2019 34
23 déc. 2004 à 13:49
pourquoi tu mets pas tout directement en String ?
Winsock recoit les données en caractères donc pas de conversion à faire.
une chaîne peut contenir n'importe quel caractère de 0 à 255 qu'il soit éditable ou non.
même si ton fichier est en binaire rien ne t'empêche de le lire dans une chaîne.

Daniel
0
retaks666 Messages postés 286 Date d'inscription jeudi 2 janvier 2003 Statut Membre Dernière intervention 16 juillet 2007
23 déc. 2004 à 13:52
Eh bien justement si, car avec les fichier texte ça marche parfaitement, mais avec les images non, de même, ouvre un fichier image avec wordpad, sélectionne tout, fait un copier/coller, tu veras l'image obtenue ne fonctionneras pas
0
Gobillot Messages postés 3140 Date d'inscription vendredi 14 mai 2004 Statut Membre Dernière intervention 11 mars 2019 34
23 déc. 2004 à 14:02
une fois le fichier écrit avec l'extension BMP, JPG, ZIP, etc...
il est parfaitement utilisable.

Daniel
0
retaks666 Messages postés 286 Date d'inscription jeudi 2 janvier 2003 Statut Membre Dernière intervention 16 juillet 2007
23 déc. 2004 à 15:26
Ben, je sais pas comment tu fait gobillot, personnellement, je prends le blocnote, je fais ouvrir, je prends un jpg, puis enregistrer sous, je remets .jpg, et ça ne fonctionne pas
0
Gobillot Messages postés 3140 Date d'inscription vendredi 14 mai 2004 Statut Membre Dernière intervention 11 mars 2019 34
23 déc. 2004 à 15:42
Ok j'ai fait l'expérience, j'ai donc pris un fichier JPG avec le bloc-notes et je l'ai réécris en JPG sans rien modifier.
donc comme tu dis ça marche pas.
évidemment j'ai chercher pourquoi, ce que j'ai vu c'est que tous les chr$(0) sont remplacés par des espaces chr$(32)
ceci étant une chose, notepad est un éditeur texte donc pas conçu pour des fichiers binaires.
mais avec VB pas de problèmes, on peut lire des fichiers binaires dans une chaîne et les réécrire tel quel, les chr$(0) ne seront pas remplacés par des espaces.

Daniel
0
Gobillot Messages postés 3140 Date d'inscription vendredi 14 mai 2004 Statut Membre Dernière intervention 11 mars 2019 34
23 déc. 2004 à 15:59
essayes ça, les 2 fichiers créés sont valables.
pour le mode Output, j'ai du mettre un point virgule pour éviter qi'il ajoute une fin de ligne à la fin.

Dim s As String

Open "C:\IMAGES\MonImage.jpg" For Binary As #1
s = Space$(LOF(1))
Get #1, , s
Close #1

Open "C:\IMAGES\MonImage1jpg" For Binary As #1
Put #1, , s
Close #1

Open "C:\IMAGES\MonImage2.jpg" For Output As #1
Print #1, s;
Close #1

Daniel
0
retaks666 Messages postés 286 Date d'inscription jeudi 2 janvier 2003 Statut Membre Dernière intervention 16 juillet 2007
23 déc. 2004 à 16:23
ok merci, mais après dur labeur j'ai enfin réeussi a traiter mes bytes comme il se doit et ça fonctionne en bytes alors je ne vais pas toucher ;) je fignole tout ça et je poste ma source ;)
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
24 déc. 2004 à 03:36
re retaks666
Mais pourquoi penses-tu que les données venues du Winsock sont des tableaux de bytes ?
Une chaine String peut contenir n'importe quel caractère de 0 à 255. Bien sûr certains caractères ne sont pas affichables, mais elles peuvent être dans une String !
Il te suffit ensuite de les enregistrer dans le fichier qui portera le nom de ton choix (JPG si tu transmets un JPG), il n'y a pas de problème !

Rappel des cours :
Un Byte est un chiffre de 0 à 255
Un Byte représente le code ascii d'un caractère
Une String est une suite de caractères.
Chaque caractère à un code ascii, donc un byte.

Mais n'essaye pas de savoir la valeur du Byte et de vouloir stocker des Bytes : Tu stockes le caractère que représente ce Byte, que ce soit un fichier texte ou un JPG.

Vala
Jack
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)
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
24 déc. 2004 à 03:39
... et (j'oublie tjrs qqchose), un chiffre est un caractère comme les autres, avec son propre code ascii.
Donc, pour la position et la taille que tu reçois, ce qui compte, c'est le caractère que représente le Byte, pas le Byte lui même !

Vala
Jack
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)
0
Rejoignez-nous