[VB.NET] Conversions de données ...

Conversions de données ... [VB.NET] - C#/.NET managed - Programmation

Marsh Posté le 04-04-2005 à 14:50:11    

Bonjour, excusez moi de faire du multiposte mais toujours sur l'envoie de fichier via les sockets et bah je crois que j'ai avancé mais je voudrais savoir autre chose :
Lorsque mon client recoit les données sous formes de bytes :

Code :
  1. Dim bytesRead as Integer = sckclient.EndReceive(asyncResult)


Donc bytesread contient effectivement le nombre d'octets que j'ai envoyés mais alors pour appeller ma procedure de "decodage" il me faut un argument en byte. Donc comment convertir BytesRead ( actuellement en Integer ) en byte ???
 
PS : j'ai essayer ca :

Code :
  1. ReDim bufferRead(CInt(bytesRead))
  2.        Call envoie.tested(bufferRead)


Ca à l'air de marcher ( d'apres le point d'arret bufferread a pris la valeur de bytesread ) mais  quand je décode le fichier et bah j'arrive pas a l'ouvrir ( mon image n'apparait pas )
 
Voici ma procedure de decodage :

Code :
  1. Public Class EnvoyerFichier
  2.     Public Sub tested(ByVal bufferFichier As Byte())
  3.         Dim fs As New FileStream("C:\florent.jpg", FileMode.CreateNew, FileAccess.Write)
  4.         Dim w As New BinaryWriter(fs)
  5.         w.Write(bufferFichier)
  6.         w.Close()
  7.         fs.Close()
  8.     End Sub
  9. End Class


 
Merci beaucoup !!!!

Reply

Marsh Posté le 04-04-2005 à 14:50:11   

Reply

Marsh Posté le 05-04-2005 à 14:36:47    

bytesReads va représenter le nombre d'octets lus, et non les octets de ton fichier ;)

Reply

Marsh Posté le 06-04-2005 à 09:09:32    

AH ok .... j'ai virer la ligne :  

Code :
  1. ReDim bufferRead(CInt(bytesRead))


Mais c'est bizarre, une fois le transfert du  fichier terminé et bah la fichier et bien crée, je peux meme lire les données ( image, son ... ) mais alors la taille plante ( elle est plus grande que celle du fichier originale )
 
Dans mon code j'ai :

Code :
  1. Dim BufferRead(4000000) as byte


ET j'ai remarqué que si je modifie la taille du buffer et que je met par exemple ca :

Code :
  1. Dim BufferRead(2048) as byte


et bah ca plante... (Normal car la taille du fichier est plus grande que la taille du buffer )
 
Si je met :

Code :
  1. Dim BufferRead(8000000) as byte


La ca marche mais si j'envoie un fichier de 4000000 Octets et bah mon fichier  transféré va prendre comme taille celle du buffer c'est à dire 8000000 Octets
 
Et ainsi de suite en fonction de la taille du buffer...
 
Donc comment faire pour faire ca :

Code :
  1. Dim BufferRead() as byte = taille du fichier envoyé


Je t'explique :
 
Pour les messages textes, je passe par un Encodage ( qui va recuperer un code puis les données à envoyées sous forme : ( 10||||ca va ?? ) DOnc apres pour le client il va decoder les bytes en string puis va appeller la procedure de décodage: Avec des "Case" si j'envoie 10||||ca va ??? et bah le code va aller dans la "Case 10 :" puis va decoder le code....
 
Ca ca marche tres bien je sais pas si on peut faire la meme chose avec un fichier non texte.
 
Merci beaucoup ce probleme me soule vraiment


Message édité par fdiedler le 06-04-2005 à 09:10:36
Reply

Marsh Posté le 06-04-2005 à 10:27:27    

Bah je viens de te dire que ta variable bytesRead représentait le nombre d'octets lus [:delarue2]  
 
Donc :
 

Dim ByteBuffer(bytesRead) As Byte


Message édité par FlorentG le 06-04-2005 à 10:27:34
Reply

Marsh Posté le 06-04-2005 à 12:00:56    

oui je sais c'est ce que j'avais fait mais alors pour la taille c'est bon mais pourquoi aucune image n'apparait si c'est une image, aucun son si c'est une musique....
Je comprends pas pourtant effectivement il ecrit bien le bon nombre d'octets...
Est ce que tu veux mes procedures pour verifier ?
 
Merci


Message édité par fdiedler le 06-04-2005 à 12:02:18
Reply

Marsh Posté le 06-04-2005 à 12:30:28    

Bon je revient ce soir je te met toutes les procedures :
 
1) Evenement click du bouton "envoyer fichier"

Code :
  1. Call envoie.ChargeFichier("C:\marie.jpg" ) [ C'est pour un test ... ]


 
2) Procedure qui ouvre et lit le fichier :

Code :
  1. Public Function ChargeFichier(ByVal fichier As String)
  2.         Dim s As FileStream
  3.         Dim file As FileInfo
  4.         file = New FileInfo(fichier)
  5.         If file.Length < 2000000000 Then '2Go
  6.             Dim info As Integer = file.Length
  7.             ' lecture des octets du fichier
  8.             ReDim buffer(CInt(file.Length))
  9.             s = New FileStream(fichier, FileMode.Open, FileAccess.Read)
  10.             s.Read(buffer, 0, CInt(file.Length))
  11.             s.Close()
  12.             Call socket.EnvoyerFichier(buffer)
  13.         Else
  14.             Throw New Exception("Le fichier transféré ne doit pas dépasser 2 Go." )
  15.         End If
  16.     End Function


 
3) Procedure d'envoie du fichier via la socket :

Code :
  1. Public Sub EnvoyerFichier(ByVal msg As Byte())
  2.         sckclient.BeginSend(msg, 0, msg.Length, SocketFlags.None, AddressOf SendCallback, sckserver)
  3.     End Sub


4) Reception des données par le client :

Code :
  1. Public Sub ReceiveCallback(ByVal asyncResult As IAsyncResult)
  2.         If sckclient.Connected Then
  3.             Try
  4.                 bytesRead = sckclient.EndReceive(asyncResult)
  5.                 Dim mesreceive As String = Encoding.UTF8.GetString(bufferRead) 'Pour les msg texte
  6.                 Dim bufferFichier(bytesRead) As Byte
  7.                 Call envoie.tested(bufferFichier) 'Appelle procedure de décodage
  8.                 If mesreceive <> "" Then RaiseEvent MessageReceive(mesreceive) ' Pour les msg texte
  9.         Catch es As Exception
  10.                 MsgBox("Erreur fatal du serveur" )
  11.             End Try
  12.         End If


5) Décodage du fichier envoyé :

Code :
  1. Public Sub tested(ByVal bufferFichier As Byte())
  2.         If File.Exists("C:\florent.jpg" ) Then
  3.             File.Delete("C:\florent.jpg" )
  4.         End If
  5.         Dim fs As New FileStream("C:\florent.jpg", FileMode.CreateNew, FileAccess.Write)
  6.         Dim w As New BinaryWriter(fs)
  7.         w.Write(bufferFichier, 0, bufferFichier.Length)
  8.         w.Close()
  9.         fs.Close()
  10.     End Sub


 
Voila je comprends pas pourquoi ca marche pas....
 
Merci !


Message édité par fdiedler le 06-04-2005 à 12:31:58
Reply

Marsh Posté le 06-04-2005 à 14:01:49    

Donc comme dit, avec les deux lignes :

Dim bufferFichier(bytesRead) As Byte
Call envoie.tested(bufferFichier) 'Appelle procedure de décodage


T'as créé un tableau de taille bytesRead, et tu le balances direct à la fonction tested... Sans l'avoir rempli :/ Aussi, le 'Call' ne sert plus, tu peux mettre simplement l'appel à la fonction

Reply

Marsh Posté le 06-04-2005 à 14:06:30    

ok Donc comment on fait pour remplir le tableau ??
POur le "call" je savais mais je prefere le mettre copmme ca quand je relis mon code c'est plus facile ...

Reply

Marsh Posté le 06-04-2005 à 14:10:36    

[:msdn]
:D

Reply

Marsh Posté le 06-04-2005 à 14:16:02    

Justement j'etais dessus mais j'ai ps trouver qurand chose ...
http://msdn.microsoft.com/library/ [...] sTopic.asp
Je sais pas si c'est ca ....
 
Est ce que tu connais le nom de la methode ce sera plus facile a chercher.
lol
Merci

Reply

Marsh Posté le 06-04-2005 à 14:16:02   

Reply

Marsh Posté le 06-04-2005 à 14:16:48    

Tu utilises un object  System.Net.Sockets.Socket ?

Reply

Marsh Posté le 06-04-2005 à 14:19:22    

oui

Reply

Marsh Posté le 06-04-2005 à 14:23:27    

Parce que la MSDN me donne la belle méthode Socket.Receive qui comporte en paramètre un tableau de Byte ;)

Reply

Marsh Posté le 06-04-2005 à 14:28:56    

j'utilise le mode asynchrome donc "Send" et "receive" ne marche pas pour mon cas. J'utilise "BeginSend" "EndSend" "BeginReceive" et "EndReceive" mais j'utilise ca !!  

Code :
  1. Public Sub ReceiveCallback(ByVal asyncResult As IAsyncResult)
  2.         If sckclient.Connected Then
  3.             Try
  4.                 bytesRead = sckclient.EndReceive(asyncResult)
  5.                 Dim mesreceive As String = Encoding.UTF8.GetString(bufferRead)
  6.                 Dim bufferFichier(bytesRead) As Byte
  7.                 Call envoie.tested(bufferFichier)
  8.                 If mesreceive <> "" Then RaiseEvent MessageReceive(mesreceive)
  9.            
  10.                 If sckclient.Connected And bytesRead > 0 Then
  11.                     Try
  12.                         'Tente de recevoir le reste des données
  13.                         sckclient.BeginReceive(bufferRead, 0, bufferRead.Length, SocketFlags.None, AddressOf ReceiveCallback, sckclient)
  14.                     Catch ex As Exception
  15.                         MsgBox("Erreur de réception client", MsgBoxStyle.Critical, "Erreur" )
  16.                         RaiseEvent MessageError(1003, "Erreur de réception de données" )
  17.                     End Try
  18.                     bufferRead.Clear(bufferRead, 0, bufferRead.Length)
  19.                 End If
  20.             Catch es As Exception
  21.                 MsgBox("Erreur fatal du serveur" )
  22.             End Try
  23.         End If
  24.     End Sub


Donc je vois pas comment le remplir en fonction des données qu'il recoit ...


Message édité par fdiedler le 06-04-2005 à 14:29:53
Reply

Marsh Posté le 06-04-2005 à 14:33:41    

Regarde la référence sur EndReceive, y'a un exemple

Reply

Marsh Posté le 06-04-2005 à 14:34:54    

Mais avec ce code :
La variable "bufferRead" contient les bytes envoyé par le serveur. Puis je crée un tableau de bytes de taille BytesRead avec :
 
Dim bufferFichier(bytesRead) As Byte
 
Et apres j'appelle Envoie.tested pour créer un new fichier puis ecrire dedans avec "Write"
 
Mais si le tableau de bytes est vide comment le remplir ?
 
 

Reply

Marsh Posté le 06-04-2005 à 14:36:08    

Ben si la variables bufferRead contient les bytes, pourquoi ne l'utilise-tu pas avec la fonctions tested ? :??:

Reply

Marsh Posté le 06-04-2005 à 14:40:21    

bah tout  simplement a cause de probleme de la taille:
Je l'ai declarer en private :
 
    Private bufferRead(4000000) As Byte
 
Mais voila si le fichier est trop gros ca va planT et si il est trop petit et bah sa taille prendra imediatemetn celle du buffer...
 
C'était le probleme que j'avais soulever plus haut dans ce topic ...
 
ET si je emt ca :

Code :
  1. Private bytesRead As Integer
  2.     Private bufferRead(bytesRead) As Byte


 
Et bah y'a une erreur : Une expression de constante est requise.


Message édité par fdiedler le 06-04-2005 à 14:41:53
Reply

Marsh Posté le 06-04-2005 à 14:41:44    

Donc copie ton bufferRead dans ton bufferFichier alors

Reply

Marsh Posté le 06-04-2005 à 14:42:35    

et comment on fait ca ?

Reply

Marsh Posté le 06-04-2005 à 14:45:27    

*soupir*
 
 
:D

Reply

Marsh Posté le 06-04-2005 à 15:02:49    

lol dosolé d'etre sur les nerfs mais ca fait 3 semaines que je suis dessus  et voila... lol
Sinon j'ai mis ca et ca a l'air de marcher :
 
  Dim bufferFichier(bytesRead) As Byte
                bufferFichier.Copy(bufferRead, bufferFichier, bytesRead)
                Call envoie.tested(bufferFichier)
 
J'ai remarquer que des que je me deconnectais et bah mon fichier contient 1 octet ? lol pourquoi ?? Pourtant il a été souvegarder !
 

Reply

Marsh Posté le 07-04-2005 à 07:34:45    

Nan c'est bon c'est régler : j'y suis presque mais bon...
Certes ca marche mais le probleme de taille du buffer est toujours la :

Code :
  1. Dim bufferFichier(bytesRead) As Byte
  2.                 bufferFichier.Copy(bufferread, bufferFichier, bytesRead)
  3.                 Call envoie.tested(bufferFichier)


Au fait il faudrais que je déclare ca en private dans toute la class comme ci :

Code :
  1. Public bytesRead As Integer
  2.     Public bufferread(bytesRead) As Byte


Mais il veut une expression de constante...
 
Si je met ca :

   Public Const bytesRead As Integer = 0
    Public bufferread(bytesRead) As Byte


et bah cette ligne plante :

Code :
  1. bytesRead = sckclient.EndReceive(asyncResult)


Car une constante ne peut pas etre la cible d'une assignation...
Or cette ligne met fin a l'envoie donc je peut pas la virer...
 
Si j'arrivais à resoudre ce pb et bah ca reglerais enfin la probleme de la taille car le buffer prendrais immédiatement la taille du fichier a chaque envoie...
 
Voila Aidez moi !!!
 
Merci
 
 
 

Reply

Marsh Posté le 07-04-2005 à 09:04:38    

Ou ça l'expression constante ?

Reply

Marsh Posté le 07-04-2005 à 10:03:56    

bah elle est la :
 
    Public Const bytesRead As Integer = 0
    Public bufferread(bytesRead) As Byte
...
mais ca marche pas .. le truc de de se debrouiller pour ne plus définir la taille du buffer avec Dim buffer(1024) as byte par exemple...


Message édité par fdiedler le 07-04-2005 à 10:05:18
Reply

Marsh Posté le 07-04-2005 à 10:05:58    

J'veux dire, pourquoi utilise-tu une constante ? Normalement on peut mettre ce que l'on veut

Reply

Marsh Posté le 07-04-2005 à 10:21:22    

ah bah parce que cela ne marche pas :
 
    * Public bytesRead As Integer
    *     Public bufferread(bytesRead) As Byte
 
Le programme me demande une expression de constante

Reply

Marsh Posté le 07-04-2005 à 10:25:25    

Sûrement parce que bytesRead est public. D'ailleurs il ne faut jamais mettre de variables membres publiques ;)

Reply

Marsh Posté le 07-04-2005 à 10:38:32    

oui ce doit etre ca mais alors comment faire pour que le buffer prennent la taille du fichier a chaque envoi : On est obliger de le declarer en public ?? non ? sinon comment faire ?
Merci

Reply

Marsh Posté le 07-04-2005 à 10:47:41    

En private il est accessible dans ta classe, donc pas de probs ;) Enfin ça dépend comment est architecturé ton truc :D

Reply

Marsh Posté le 07-04-2005 à 11:08:13    

justement il est deja en private :
 
    Private bytesRead As Integer
    Private bufferread(bytesRead) As Byte
 
MAIS j'ai tjrs l'erreur ...
T'a pas une idée ?

Reply

Marsh Posté le 07-04-2005 à 11:13:06    

Y'a-t-il vraiment un interêt à avoir cette variable dans le corps de la classe ? Ca pose problème si tu la déclare localement dans la fonction ?

Reply

Marsh Posté le 07-04-2005 à 11:24:50    

Dans la procedure receive ca pose pas de pb mais regarde :
Code :
 
    * Dim bufferFichier(bytesRead) As Byte
    *
    *                 bufferFichier.Copy(bufferread, bufferFichier, bytesRead)
    *
    *                 Call envoie.tested(bufferFichier)
 
 
et j'ai definie  Dim buuferRead(4000000) as byte  
mais ca prends bcp de mémoire et si le fichier depasse cette valeur et bah ca plante c'est pour ca que je peux pas definir la taille du buffer ...


Message édité par fdiedler le 07-04-2005 à 15:58:03
Reply

Marsh Posté le 07-04-2005 à 15:58:14    

Au fait voila comment je vois les choses :
 
J'ai créer une class qui encode :
 
Si je veux envoyer ca "Slt !!!!" en taille 10, en arial :
Et bah je vais apeller ma class puis a la fin voila ce qui va etre envoyé :
20 (Code d'envoie pour des messages texte )|||| Pseudo + "dit" |||| 10 ( taille ) |||| "Arial" |||| red |||| false (gras) |||| false (italique)
 
Puis tout ca va se retrouver dans le bufferRead et puis  dans l'evenement que j'ai créer "MessageReceive" et bah je vais appeller ma procedure qui va decoder tout ca ...
et puis ds le Case 20 : 'Afficher le texte decoder...
 
et voila le travail !!!
 
Maintenant il faudrait faire ca aussi avec l'envoie de fichier :
 
J'ai deja preprogrammer le code d'envoie pour les fichier ( 30 ) mais alors il faut savoir que tout est en String puis avant l'envoie dans la procedure Socket.send et bah je l'encode en Bytes...

Code :
  1. Public Sub Send(ByVal Data As [String])
  2.         buffer = Encoding.UTF8.GetBytes(Data)
  3.         sckclient.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, AddressOf SendCallback, sckclient)
  4.     End Sub


 
Donc il faudrait envoyer un truc du genre :
30 ( Code envoie de fichier ) |||| Pseudo + "Vous envoie" + FileName ( optionnel ) |||| Contenue du fichier en String
 
Maintenant comment recuperer les données du fichier en String et non en Byte ( comme j'ai fais ci-haut ) ????
 
Merci beaucoup pour ton soutient
 
Fdiedler

Reply

Marsh Posté le 07-04-2005 à 16:04:23    

Et si tu utilisais le .NET remoting ? [:dawa] Tu sérialize ta classe, avec tes différents champs (pseudo, taille, police), puis tu désérialize de l'autre côté, ce serait 100x plus simple ;)

Reply

Marsh Posté le 07-04-2005 à 16:17:18    

bah j'ai deja develloper mon application avec les socket. De plus je connais pas du tout le remoting et je sais aps si je devrais tout modifier ou pas ....

Reply

Marsh Posté le 07-04-2005 à 16:17:51    

Faut regarder dans la MSDN comment ça marche :)

Reply

Marsh Posté le 07-04-2005 à 16:23:50    

Mais tu penses que ca va regler mes pb ?? et est ce que la connection et tout ca je devrais recommencer ?

Reply

Marsh Posté le 07-04-2005 à 16:26:06    

Pas sûr. En tous cas, ça sera 50 000 fois moins galère à faire

Reply

Marsh Posté le 07-04-2005 à 16:39:19    

J'ai vu sa et je trouve que c'est plus difficile...
De plus c'est un autre moyen de communication reseau donc j'utiliserais plus les sockets. Or ca fait 2 mois que je developpe mon Chat et donc j'ai pas trop envie de recommencer tout... Donc je vais essayer de trouver une solution...
 
Pour l'encodage j'ai utiliser ca :
 
            Dim ascii As New ASCIIEncoding
            Dim decode As String = ascii.GetString(buffer)
 
Mais bon a mon avis c'est pas bon. Pour le code d'envoie de fichier y'a pas de probleme sinon il va bien dans le Case 30 : 'et puis la j'apelle ma class qui endecode les string en byte puis le ecrit dans un autre ficher.
 
Mais bon le resultat n'est pas la.
 
Faudrais peut etre que je t'envoie mes class par mail complete pour que tu comprenne mieux mon systeme?


Message édité par fdiedler le 07-04-2005 à 16:44:43
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed