Partage
  • Partager sur Facebook
  • Partager sur Twitter

transfert de fichier binaire via les sockets

Sujet résolu
    21 mars 2012 à 20:58:08

    bonsoir

    j'ai trouve un code sur le web et j'ai le modifie afin qu'il puisse transferer un fichier (.bmp) de serveur
    au client
    le problem est que le programme client genere un fichier de meme taille que le fichier source mais de contenu different !!
    je n'ai pas pu ouvrire le fichier
    donc j'ai utilisé le hex editor et j'ai trouve une difference et un decalage !!
    voici le code de serveur
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Net.Sockets;
    using System.Net;
    using System.IO;
     
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main (String[] args)
            {
                // 1. to create a socket
                Socket sListen = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
     
                // 2. Fill IP
                IPAddress IP = IPAddress.Parse ("127.0.0.1");
                IPEndPoint IPE = new IPEndPoint (IP, 4321);
     
                // 3. binding
                sListen.Bind (IPE);
     
                // 4. Monitor
                Console.WriteLine ("Service is listening ...");
                sListen.Listen (2);
     
                // 5. loop to accept client connection requests
                while (true)
                {
                    Socket clientSocket;
                    try
                    {
                        clientSocket = sListen.Accept ();
                    }
                    catch
                    {
                        throw;
                    }
     
                    // send data to the client
                    //clientSocket.Send (Encoding.Unicode.GetBytes ("I am a server, you there?? !!!!"));
     
                    // send the file
                    byte[] buffer = ReadImageFile ("lol.bmp");
    
                    clientSocket.Send (buffer, buffer.Length, SocketFlags.None);
                    Console.WriteLine ("Send success!");
                }
            }
     
            private static byte[] ReadImageFile (String path)
            {
                FileInfo fileinfo = new FileInfo (path);
                byte[] buf = new byte[fileinfo.Length +4];
                FileStream fs = new FileStream (path, FileMode.Open, FileAccess.Read);
                fs.Read (buf, 0, buf.Length);
                fs.Close ();
                //fileinfo.Delete ();
                for (int i = buf.Length-1;i<=0;i--)
                {
                    buf[i+4]=buf[i];
                }
                
                buf[0] = (byte)(buf.Length & 0X00FF);
                buf[1] = (byte)((buf.Length & 0XFF00) >> 8);
                buf[2] = (byte)((buf.Length & 0XFF0000) >> 16);
                buf[3] = (byte)((buf.Length & 0XFF000000) >> 24);
                
                int taille = 0;
    
                taille = buf[0] + (buf[1] << 8) + (buf[2] << 16) + (buf[3] << 24);
                
                Console.WriteLine("taille de fichier "+taille+" taille de buf"+ buf.Length);
                
                GC.ReRegisterForFinalize(fileinfo);
                GC.ReRegisterForFinalize (fs);
                return buf;
            }
     
        }
    }
    

    et voici le code de client
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Net.Sockets;
    using System.Net;
    using System.IO;
    
    namespace ConsoleApplication2
    {
        class Program
        {
            static void Main(String[] args)
            {
                // 1. to create a socket
                Socket S = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    
                // 2. fill in the remote IP
                IPAddress IP = IPAddress.Parse("127.0.0.1");
                IPEndPoint IPE = new IPEndPoint(IP, 4321);
    
                Console.WriteLine("started connection service ....");
                // 3. connect to the server
                S.Connect(IPE);
    
                // 4. receive data
                byte[] buffer = new byte[5000000];
                S.Receive(buffer, buffer.Length, SocketFlags.None);
                //var Msg = Encoding.Unicode.GetString (buffer);
                //Console.WriteLine ("received message: (0)", msg);
    
                //traitement du byte recu 
                int taille = 0;
                taille = buffer[0] + (buffer[1] << 8) + (buffer[2] << 16) + (buffer[3] << 24);
                Console.WriteLine(taille);
                for (int i = 0; i < taille;i++ )
                {
                    buffer[i] = buffer[i + 4];
                }
                //
                Console.WriteLine("Receive success");
    
                FileStream fs = File.Create("lol.bmp");
                fs.Write(buffer, 0, taille-1);
                fs.Close();
    
                Console.ReadKey();
            }
        }
    }
    

    pouvez m'expliquer pour quoi ca ne fonctionne pas et merci d'avance
    • Partager sur Facebook
    • Partager sur Twitter
      22 mars 2012 à 2:10:48

      Dans ta méthode qui lit le contenu du BMP côté serveur :

      Citation : med linux


      for (int i = buf.Length-1;i<=0;i--)
      {
          buf[i+4]=buf[i];
      }
      



      Tu ne vois rien de suspect ? :)

      Au fait, c'est une mauvaise idée de décaler les octets comme ça, alors que tu as cette ligne juste avant:
      fs.Read(buf, 0, buf.length);
      

      Le deuxième paramètre sert à indiquer la position à partir de laquelle tu veux placer le contenu du fichier dans le tableau buf. Il aurait suffit de mettre 4 au lieu de 0, et le tour était joué ! ;)
      • Partager sur Facebook
      • Partager sur Twitter
        22 mars 2012 à 11:31:09

        ok merci ;
        j'ai une autre question

        quand je veux transferer un fichier d'une taille de (+500ko par exemple ) est ce qu'il faut l'envoyer par des segments au tous le fichier a la fois ?
        • Partager sur Facebook
        • Partager sur Twitter
          22 mars 2012 à 12:38:19

          Tu peux l'envoyer en une fois. Cependant, ça ne veut pas dire qu'il arrivera en une fois (!) Il est parfaitement possible que le paquet soit automatiquement découpé en morceaux plus petits à une étape du parcours. Donc de manière générale tu dois être plus prudent à la réception, observer le nombre d'octets reçus et éventuellement boucler en appelant la méthode Receive de ton socket jusqu'à avoir reçu le nombre d'octet souhaité (que tu auras normalement "annoncé" au début).

          A cet égard les classes TcpListener et TcpClient sont plus faciles d'emploi que les sockets, je t'invite donc à les utiliser de préférence.

          PS, petite remarque par rapport à ton code : tu ne devrais pas appeler la méthode GC.ReRegisterForFinalize(truc), mais plutôt truc.Dispose(). Ou mieux, utilise un bloc using pour être sûr que le Dispose soit appelé quoiqu'il arrive.
          • Partager sur Facebook
          • Partager sur Twitter
            22 mars 2012 à 13:02:04

            merci beaucoup :D
            j'ai déclare un tableau de taille (5000000) pour recevoir une image de taille 5mo
            quand j'utilise buffer.length il me donne la taille de tableau
            comment faire pour connaitre le nombre d'octets reçu ??
            • Partager sur Facebook
            • Partager sur Twitter
              22 mars 2012 à 13:19:03

              Le nombre d'octets reçus est la valeur renvoyée par la méthode Receive (qui peut donc être inférieure au nombre d'octets envoyés). Et déclarer un tableau de 5 Mo "au cas où", c'est un peu excessif... :-°
              • Partager sur Facebook
              • Partager sur Twitter
                22 mars 2012 à 15:16:55

                merci vous m'avez vraiment aidé ^^
                • Partager sur Facebook
                • Partager sur Twitter

                transfert de fichier binaire via les sockets

                × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                • Editeur
                • Markdown