Problème transfert winsock

retaks666 Messages postés 286 Date d'inscription jeudi 2 janvier 2003 Statut Membre Dernière intervention 16 juillet 2007 - 22 déc. 2004 à 02:54
zeunz Messages postés 200 Date d'inscription jeudi 26 février 2004 Statut Membre Dernière intervention 30 juin 2008 - 17 janv. 2005 à 22:49
bonjour, j'ai un problème, lorsque je copie un fichier par winsock, le fichier copier diffère quelque peut, par exemple, un caractère vas être répéter deux fois etc, voici mon code, aidez moi svp
Public Sub sendnext()
If bytessent > LOF(1) Then Exit Sub
 'Ouverture du fichier en binaire
            If position + 16 < LOF(1) + 1 Then '< lof(1)+1 equivalent <= lof(1)
                Get #1, position, Buffer
                Form1.Wsk.SendData Buffer
                position = position + 16
                bytessent = bytessent + 16
                ElseIf position + 16 > LOF(1) And position < LOF(1) Then  'au cas ou la taille du fichier n'est pas un multiple de 8
                ReDim Buffer(LOF(1) - position) 'Redimmensionnement du tableau Buffer
                Get #1, position + 1, Buffer
                Form1.Wsk.SendData Buffer
                DoEvents
                'MsgBox "dernier bout " & Form1.ByteToString(Buffer())
                bytessent = bytessent + (LOF(1) - position)
                Close #1
                Form1.Wsk.SendData "Fin du transfert"
                Form1.Wsk.Close
                Exit Sub
           End If

Form1.prgprogres.Value = bytessent
Form1.Lblrecu = bytessent
End Sub

'dans le winsock data arrival:
            Open CD1.FileName For Binary As #2
            Seek #2, 1
(...)
Put #2, , bufftmp
Wsk.SendData "ok"

'dans le client...
If donnee = "ok" Then
sendnext
Exit Sub
End If


HELP ME PLESE :s

4 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
22 déc. 2004 à 03:56
Salut retaks666
Tu t'es bien compliqué la vie ...
Pourquoi ne pas expédier le fichier en une fois ?
Là, tu envoies 16 octets à la fois, mais comme le rythme n'est cadensé que par DoEvents, c'est comme si tu envoyais tout en même temps (d'où la complexité inutile).

Par contre, côté réception, tu es vraiment léger :
En effet, avec un winsock (WS), on peut envoyer autant de données d'un coup (quit à saturer la machine), mais la réception se fait au rythme de la vitesse de réception (vitesse du réseau) et d'un élément incontrôlable, le buffer de réception.
Quand la machine a du temps machine, elle génère l'évènement DataArrival, même si tout n'a pas encore été reçu.
Donc, pour l'instant, si tu ne transfères que de petits fichiers sur ton réseau local, tu ne vas pas t'en apercevoir, mais les choses vont de compliquer si un des paramètres varie (charge réseau ou taille fichier).
Il faut donc procéder comme cela (et de nouvelle questions vont apparaitre) :
Dans la Sub du DataArrival, il te faut écrire les données dans le fichier, mais au bon endroit. Dans ton cas, tu replaces le 'curseur' du fichier au début avec le Seek, donc si tu reçois le fichier en plusieurs fois, tu ne récupèreras que les derniers octets dans le fichier.
Pour mémoriser l'emplacement :
Dans la Sub du DataArrival, déclare une variable comme ceci :
Static QteRecue As Long
C'est un dimensionnement spécial qui gerde en mémoire la valeur entre deux exécution du programme.
A chaque données que tu vas recevoir, il te suffira d'ajouter le nombre d'octets reçus à cette mémoire et au coup d'après, faire un 'Seek #2, QteRecue' à la place.

Ensuite, tu t'apercevras qu'il faut pourvoir remettre à zéro cette mémoire entre deux fichiers : A toi de jouer avec la donnée 'Ok' que tu expédies.

Cette solution est empirique, il y a d'autres techniques pour identifier les paquets envoyés : Les numéroter :
Imagine que, côté expéditeur, à chaque fois que tu envoies des données, tu ajoutes, en tête de trame, la position équivalente à l'emplacement de ces données dans le fichier :
Au lieu d'envoyer directement les octets, il te suffit d'envoyer :
WS.SendData CStr(Position) & "#" & CStr(LongueurDesDonnées) & "#" & 'les octets du fichier'
Côté réception, tu n'as plus qu'à isoler les 2 premiers paramètres pour savoir où et combien de données à écrire.
Pour les isoler, le plus simple est d'utiliser un tableau et la fonction Split :
Dim Tablo() As String
Tablo = Split(DonnéesReçues, "#")
Dans Tablo(0) : Tu auras la position
Dans Tablo(1) : La longueur des données
... facile à exploiter ensuite.

Imagine ce même genre de protocole (maison) pour envoyer d'autres infos, comme par exemple le nom du fichier (utile quand même, non ?)
On reprend le même schéma et on lui ajoute un mot clé au début :
WS.SendData "Données" & "#" & CStr(Position) & "#" & CStr(LongueurDesDonnées) & "#" & 'les octets du fichier'
Dans Tablo(0) : le mot clé "Données"
Dans Tablo(1) : Tu auras la position
Dans Tablo(2) : La longueur des données
Avec le mot clé "Données", tu pourras orienter ton programme pour savoir quoi faire des infos qui suivent.

Ensuite, pour transférer le nom du fichier, facile, suffit de changer de mot clé :
WS.SendData "NomFichier" & "#" & "LeNomDuFichier"
A la réception, quand tu recevras le mot clé "NomFichier", bah tu sauras qu'il faut préparer un fichier de réception portant ce nom là.
Pour séparer la programmation propre à chaque mot clé (que tu retrouveras toujours dans le Tablo(0)), il suffit d'utiliser la fonction Select :
Select Case Tablo(0)
Case "NomFichier"
... les lignes de programme pour mémoriser cette donnée
Case "Données"
... les lignes de programme pour écrire le fichier
End Select

Tu pourras ainsi aisément te créer des mots clés afin de faciliter le transfert de nouvelles infos.

(Fin du roman)
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
retaks666 Messages postés 286 Date d'inscription jeudi 2 janvier 2003 Statut Membre Dernière intervention 16 juillet 2007
22 déc. 2004 à 13:24
Merci jack, je vais essayer ... Mais d'abord je vais essayer de faire une liste d'envoi avec le sendcomplete
0
retaks666 Messages postés 286 Date d'inscription jeudi 2 janvier 2003 Statut Membre Dernière intervention 16 juillet 2007
22 déc. 2004 à 22:43
bon, j'ai opté pour ta solution, mais j'ai un problème
Form1.Wsk.SendData CStr(position) & "#" & UBound(Buffer) & "#" & Buffer()
ne fonctionne pas, je dois donc convertir les bytes en string, le problème est que cela fonctionne lors de fichier texte, mais si je veux envoyer d'autres type, comme les zip ou les images etc, inévitablement certains caractères ne pourront être transtypés, donc problème
0
zeunz Messages postés 200 Date d'inscription jeudi 26 février 2004 Statut Membre Dernière intervention 30 juin 2008
17 janv. 2005 à 22:49
salut je ss sur le meme truc, ms la, je m'arrache les cheveux.
j'ai pose ma question:
http://www.vbfrance.com/forum.v2.aspx?ID=372630

si c'est possible de pouvoir repondre ames questions, merci

salutations.

zeunz
0
Rejoignez-nous