transfert de fichier, client serveur

transfert de fichier, client serveur - C#/.NET managed - Programmation

Marsh Posté le 26-11-2009 à 15:15:07    

salut
je voudrais faire un serveur munti-clients simple qui envoi un fichier a chaque client qui se connecte. j'ai fait le code suivant, mais comme je suis débutant en C# je vous demande si c'est une bonne façon de faire:
 
Serveur:
 

Code :
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Net;
  6. using System.Net.Sockets;
  7. using System.IO;
  8. using System.Threading;
  9. namespace socket
  10. {
  11.     class Serveur
  12.     {
  13.         private static string FILE_NAME;
  14.         public static void ThreadProc(object obj)
  15.         {
  16.             TcpClient c = (TcpClient)obj;
  17.             Stream str = c.GetStream();
  18.             byte[] b;
  19.             try
  20.             {
  21.                 FileStream fs = new FileStream(FILE_NAME, FileMode.Open, FileAccess.Read);
  22.                 BinaryReader r = new BinaryReader(fs);
  23.                 while (r.BaseStream.Position < r.BaseStream.Length)
  24.                 {
  25.                     b = Encoding.ASCII.GetBytes(r.ReadString());
  26.                     str.Write(b, 0, b.Length);
  27.                 }
  28.                 r.Close();
  29.                 fs.Close();
  30.                 str.Close();
  31.                 c.Close();
  32.             }
  33.             catch (Exception e)
  34.             {
  35.                 Console.Error.WriteLine(e.StackTrace);
  36.             }
  37.         }
  38.         static void Main(string[] args)
  39.         {
  40.             /*******************/
  41.             FILE_NAME = "data.txt";
  42.             if (File.Exists(FILE_NAME))
  43.             {
  44.                 Console.WriteLine("Fichier existant !" );
  45.                 Console.ReadKey(true);
  46.                 return;
  47.             }
  48.             FileStream filestr = new FileStream(FILE_NAME, FileMode.CreateNew);
  49.             BinaryWriter w = new BinaryWriter(filestr);
  50.             w.Write("Le contenu du text a envoyer.\n" );
  51.             w.Close();
  52.             filestr.Close();
  53.             /*******************/
  54.             IPHostEntry iphe = Dns.Resolve("localhost" );
  55.             IPEndPoint ipep = new IPEndPoint(iphe.AddressList[0], 8080);
  56.             TcpListener s = new TcpListener(ipep);
  57.             s.Start();
  58.             while(true)
  59.             {
  60.                 TcpClient c = s.AcceptTcpClient();
  61.                 Thread t = new Thread(new ParameterizedThreadStart(ThreadProc));
  62.                 t.Start(c);
  63.             }
  64.         }
  65.     }
  66. }


 
client:
 

Code :
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Net;
  6. using System.Net.Sockets;
  7. using System.IO;
  8. namespace socketclient
  9. {
  10.     class Client
  11.     {
  12.         static void Main(string[] args)
  13.         {
  14.             string FILE_NAME = "data.txt";
  15.             while (File.Exists(FILE_NAME))
  16.             {
  17.                 string nb = (new Random().Next(0, 100)).ToString();
  18.                 FILE_NAME = "data_" + nb + ".txt";
  19.             }
  20.             FileStream fs = new FileStream(FILE_NAME, FileMode.CreateNew);
  21.             BinaryWriter w = new BinaryWriter(fs);
  22.             TcpClient c = new TcpClient("localhost", 8080);
  23.             Stream str = c.GetStream();
  24.             Console.WriteLine("Client connected" );
  25.             byte[] b = new byte[50];
  26.             String sb;
  27.             int i;
  28.             if ((i = str.Read(b, 0, 50)) != -1)
  29.             {
  30.                 sb = Encoding.ASCII.GetString(b);
  31.                 w.Write(sb);
  32.             }
  33.             w.Close();
  34.             fs.Close();
  35.             str.Close();
  36.             c.Close();
  37.             Console.ReadKey(true);
  38.         }
  39.     }
  40. }


 
merci

Reply

Marsh Posté le 26-11-2009 à 15:15:07   

Reply

Marsh Posté le 26-11-2009 à 21:51:00    

up

Reply

Marsh Posté le 28-11-2009 à 12:51:11    

déjà le "while(true)" c'es tpas terrible.  
sinon pour tes flux, c'est foireux aussi. En cas d'exception, tu ne fermes pas tes flux. Tu risques que le fichier soit locké dans ce cas.  
 
Ensuite, si ton fichiers contient des caractères spéciaux, en ASCII tu risques d'avoir des pertes.


---------------
quand un homme raisonne mal c'est qu'il n'a pas les données pour raisonner mieux (diderot)
Reply

Marsh Posté le 28-11-2009 à 13:48:48    

moi23372 a écrit :

déjà le "while(true)" c'es tpas terrible.


Pourquoi ? Le serveur tourne sans arrêt, non ?
 

moi23372 a écrit :

Ensuite, si ton fichiers contient des caractères spéciaux, en ASCII tu risques d'avoir des pertes.


Donc je dois faire comment ?

Reply

Marsh Posté le 29-11-2009 à 20:06:38    

et quoi le jour ou tu veux arrêter, tu kill le process? pas terrible comme solution. Il faut au moins prévoir une porte de sortie.  
 
Pour l'ASCII, faut plutot passer en UNICODE.


---------------
quand un homme raisonne mal c'est qu'il n'a pas les données pour raisonner mieux (diderot)
Reply

Marsh Posté le 30-11-2009 à 15:42:54    

Suis-je obligé de transformer les données en mode binaire pour les envoyer via socket, ou bien je peux es envoyer sous forme de chaine de caractère directement ?

Reply

Marsh Posté le 02-12-2009 à 20:39:39    

les sockets fonctionnent en binaire.


---------------
quand un homme raisonne mal c'est qu'il n'a pas les données pour raisonner mieux (diderot)
Reply

Marsh Posté le 08-12-2009 à 17:04:28    

Je me souviens qu'en langage C je pouvais envoyer directement une chaine de caractères via socket.

Reply

Marsh Posté le 08-12-2009 à 20:11:36    

ça je ne crois pas. Ayant fait du C, les sockets fonctionne bien en binaire en C


---------------
quand un homme raisonne mal c'est qu'il n'a pas les données pour raisonner mieux (diderot)
Reply

Marsh Posté le 09-12-2009 à 14:23:55    

moi23372 a écrit :

ça je ne crois pas. Ayant fait du C, les sockets fonctionne bien en binaire en C


ben regarde le 2eme argument de send par exemple:
int send(int sockfd, const void *msg, int len, int flags);
 
Un code typique pourrait être:
 

Code :
  1. char *msg = "ssmr was here";
  2.     int len, bytes_sent;
  3.     ...
  4.     ...
  5.     len = strlen(msg);
  6.     bytes_sent = send(sockfd, msg, len, 0);
  7.     ...
  8.     ...


Source: http://vidalc.chez.com/lf/socket.html#sendrecv
 
Je ne sais pas si on peux en C# envoyer une chaine de caractères directement comme ça.


Message édité par ssmr le 09-12-2009 à 14:25:10
Reply

Marsh Posté le 09-12-2009 à 14:23:55   

Reply

Marsh Posté le 13-12-2009 à 17:21:34    

en c c'est bien un pointeur (void *).  En c# c'est du binaire (tout comme en java).  
Pour convertir il suffit d'utiliser la classe Encoding.Unicode.GetBytes(String str);


---------------
quand un homme raisonne mal c'est qu'il n'a pas les données pour raisonner mieux (diderot)
Reply

Marsh Posté le 08-01-2010 à 14:39:09    

Ouais, enfin si t'envoies directement les bytes lis par ton filestream, t'auras pas à t'emmerder à les décoder en texte pour les réencoder pour rien...
 
Sinon, je me suis toujours demandé moi aussi comment faire pour qu'une application console attende gentiment sans s'arrêter. le while(true) c'est naze, ok, mais quoi mettre d'autre ?

Reply

Marsh Posté le 08-01-2010 à 18:07:56    

Nan, c'est pas ça mon problème...

 

Quand c'est qu'une application Forms ou Service, pas de souci, tu ne sors jamais du programme tant que tu ne le ferme pas explicitement.

 

Mais dans une Console, ça sort direct, je sais pas comment le mettre en pause sans while :D


Message édité par MagicBuzz le 08-01-2010 à 18:08:32
Reply

Marsh Posté le 08-01-2010 à 23:13:08    

Ben je vois un truc genre un readkey qui bloque le programme (et quand on appuie sur une touche, ça quitte le programme)
Et on joue avec les évènements asynchrones des sockets... ça devrait le faire, mais c'est à tester

Reply

Sujets relatifs:

Leave a Replay

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