colletmick
Messages postés5Date d'inscriptionvendredi 2 avril 2004StatutMembreDernière intervention 9 octobre 2006
-
8 oct. 2006 à 13:35
colletmick
Messages postés5Date d'inscriptionvendredi 2 avril 2004StatutMembreDernière intervention 9 octobre 2006
-
9 oct. 2006 à 17:34
Bonjour,
Je me permet de venir poser ma question ici, je n'arrive pas avoir de renseignement ailleur.
Je suis sur une application client/seveur en csharp depuis quelque temps, j'arrive bien a faire communiquer les deux applications ensemble en envoyant du texte via le networkstream, cependant j'aimerai pouvoir faire passer egalement, des arrays(tableaux), des images, des fichiers ect...
Mais je ne sais pas du tout comment faire.
Quelqu'un pourrait il m'aider?
Merci
taupe4
Messages postés91Date d'inscriptiondimanche 16 avril 2006StatutMembreDernière intervention17 avril 20081 9 oct. 2006 à 01:30
Moi je communique entre les applications en binaire pour mon chat, donc aucun problème à ce sujet. Avant, j'utilisais effectivement du texte, mais ça m'a vite posé problème ( surtout en termes de visioconférence, ça diminue sensiblement la charge de ne pas sérialiser/désérialiser 24 fois (2x12) par seconde )
Cela implique une refonte du moteur de chat et la compréhension des BinaryReader/BinaryWriter. Mais l'amélioration des performances en vaut le temps et surtout la modularisation possible.
Au début mon chat se basait sur le moteur de Winchat (L'application venant avec le .NET SDK), mais j'ai vite été limité. J'ai reconstruit un moteur de chat que je nomme PowerChat, et qui supporte compression,cryptage,multiclient, optimisé (et combinaisons possibles). Il permet aussi de mettre en place un chat à la winchat, avec un espace de texte par utilisateur (utile en développement avec le colorateur syntaxique intégré). Ce type de chat fonctionne en envoyant uniquement les changements faits (ajout d'un char, backspace, coller, etc.) ce qui réduit encore plus la conso de bande passante.
Tests (visioconférence + mode espaces multiples):
Chat 1.0 alpha 1 (basé sur Winchat 1.0) : 12,7 Mo en 45 minutes
PowerChat 1.0 alpha 1 (basé sur PowerChat Core 1.0 mode compressé optimisé multiclients (3)): 3,7 Mo (9,1 Mo pour l'hôte)* en 45 minutes
*L'hôte est le client PCC qui s'occupe de transférer les données à tous les clients, il y a donc toute la visioconférence qui transite, ainsi que les fichiers et le texte.
Tout ça sera disponible sur CS lorsque tout sera fini, optimisé et débogué (j'ai une belle liste de bogues en mode compressé, surtout d'un problème de redondance, de problèmes de longueur de données erronées, etc.)
Tout ça pour dire que si tu peux, sers toi d'une communication binaire avec le NetworkStream. Une fois que c'est fait, les avantages sautent aux yeux (sérialisation inutile, réutilisation facile,etc.). Personnellement je m'en sers pour un streaming audio-vidéo entre 2 usagers (fortement compressé, mais qui permet une communication fluide entre deux connexions 56 Ko (ce qui était vraiment difficile en mode texte)
P.S. Tout ce qui est en petit est inutile. Je raconte un peu trop
colletmick
Messages postés5Date d'inscriptionvendredi 2 avril 2004StatutMembreDernière intervention 9 octobre 2006 9 oct. 2006 à 09:26
Ton explication m'interesse beaucoup, mais serais-ce efficace dans le transfere de fichier?
Mon probleme actuel est de faire passer un tableau par le protocole, ta solution resoudrait elle mon probleme?
taupe4
Messages postés91Date d'inscriptiondimanche 16 avril 2006StatutMembreDernière intervention17 avril 20081 9 oct. 2006 à 17:21
Tu pourais par exemple envoyer dans le protocole les infos suivantes: ArrayInt,12,[valeurs] (un peu du genre sérialisation mais en version perso), pour ensuite récupérer un tableau de 12 int très facilement.
Le problème avec la sérialisation c'est qu'elle copie tout, elle conserve même des paramètres inutiles (language, etc.).
Moi dans mon protocole ça communique comme suit: byte, [object]; le premier octet indique la nature des données (message,fichier,vidéo,audio,wizz,coupure,etc.). Le reste dépend de l'objet (fichier = poids, nom distant, données ; coupure = client).
Pour les tableaux, en binaire, tu as le choix: sérialisation .net ou ta propre sérialisation (souvent meilleure). En transférant que du texte, ça le dit: tes données seront transformées en texte, avec les Int32, tu passes de quatre octets à un nombre d'octets correspondant à la longueur de l'Int (320324 = 6 octets). Tandis qu'en binaire tu envoie un octet pour dire "Int32" et 4 octets avec ton nombre. Avec un tableau de Int32 tu rajouteras un byte, un ushort ou un uint pour dire la taille de l'array (à toi de voir ce que tu as besoin, je te donne des types non signés car un tableau ne peut pas contenir -x données
En gros, en binaire tu prends un peu plus de temps mais tu économises de la bande passante. Et ta propre sérialisation te permet de ne pas copier les données ("IsSerialized, IsFixedSize,etc.) inutiles. En texte pur, tu dois convertir toutes tes données en texte (ou en base 64, ce qui alourdit considérablement un fichier).
Voici un code qui pourrait transférer un array d'un receveur à un client, sauf qu'ici on prend un MemoryStream:
MemoryStream ms = new MemoryStream();
BinaryReader br = new BinaryReader(ms);
BinaryWriter bw = new BinaryWriter(ms);
byte intcode = 2; //code qui dit qu'on envoie un tableau de int
//Partie d'envoi
int[] ints = new int[]{1,2,3,4};
bw.Write(intcode); //Envoi du code "ArrayInt"
bw.Write((byte)ints.Length); //Envoi de la longueur du tableau
foreach (int i in ints) bw.Write(i); //Chaque int est envoyé
//Cette partie sert à remettre le pointeur dans le fichier à 0, mais dans un NetworkStream, elle est inutile
ms.Position = 0;
//Partie Réception
byte recCode = br.ReadByte();
if (recCode == intcode){//Si on envoie un tableau d'Int32
byte longueur = br.ReadByte();
int[] generated = new int[longueur];
for(byte i=0;i<longueur;i++){
generated[i] = br.ReadInt32();
}
//Exploitation du tableau ici
foreach (int i in generated) MessageBox.Show(i.ToString());
}
En gros, tu vois le principe , tu verras à l'éxécution de code des MessageBox disant 1,2,3,4 (à la suite). Là, tout ce qu'on fait, ç'est faire passer des données à travers un flux et les lire, rien de compliqué.
Pour envoyer des messages, tu dis que si recCode == 1 par exemple, tu fais ReadString() (et pour envoyer tu fais .Write("....."))
D'accord, pour les tableaux, c'est quand même un peu de sérialisation, mais ça permet beaucoup
colletmick
Messages postés5Date d'inscriptionvendredi 2 avril 2004StatutMembreDernière intervention 9 octobre 2006 9 oct. 2006 à 17:34
Je test ca ce soir, je te tiens au courant demain matin à la premiere heure, merci en tout cas c'est bien gentil a toi de me consacrer un peu de ton temps.