Ca rame sévère !

Résolu
billou_13 Messages postés 860 Date d'inscription jeudi 4 mars 2004 Statut Membre Dernière intervention 19 août 2014 - 3 févr. 2005 à 18:23
 cs_JuS - 24 mai 2005 à 11:50
Voila, g fait un programme serveur en utilisant les NetworkStream et je c pas pourquoi, dès qu'il y a 3 clients minimum, le serveur se met a ramer sévère. Alors je voulais savoir ce que vous pensez de mon code. Est-ce que c a cause de mon code ?

Voila mon code commenté (merci d'avance pour les lecteurs) :


using System;

using System.Collections;

using System.IO;

using System.Net;

using System.Net.Sockets;

using System.Threading;


namespace Serveur_NetworkStream_Objets
{

//On créé un objet client
//Ainsi, on créé un tableau pour tous les clients connectés
class Client
{

public
int Numero;

public
bool Connecte;
//Booléen pour savoir si le client est connecté
public NetworkStream NS;
//Contient le flux réseau du client avec le serveur
public StreamReader SR;
//Flux pour écouter le client
public StreamWriter SW;
//Flux pour parler au client

//Constructeur de l'objet client
public Client(
int New_Numero, NetworkStream New_NS)
{
Numero = New_Numero;
Connecte =
true;

NS = New_NS;
SR =
new StreamReader(NS);
SW =
new StreamWriter(NS);
}



//Fonction qui écoute le client et poste les messages reçus sur la console
public
void Ecouter()
{

string Message_Recu;
Console.WriteLine("Ecoute du client {0}",Numero);

while (Connecte)
//Tant que le client reste connecté
{

try
{

//On attend un message dans le flux pour écouter
//et dès qu'il y a quelque chose, on le met dans Message_Recu
Message_Recu=SR.ReadLine();

Console.WriteLine("Client {0} : {1}",Numero,Message_Recu);

}
//En cas d'erreur dans le flux, on déconnecte le client
catch(Exception e)
{
Console.WriteLine("Erreur avec le client {0}, déconnection du client !",Numero);
Connecte =
false;
}
}
//Fin de tant qu'il est connecte (Connecte=true)
//Client déconnecté, on ferme tous les flux
SR.Close();
SW.Close();
NS.Close();
}





//Fonction qui permet d'envoyer un message au client
public
void Envoyer(String Message)
{
SW.WriteLine(Message);
SW.Flush();
}


}



class Serveur
{

[STAThread]

static
void Main(
string[] args)
{

int Port = 1313;
//Numéro du port
TcpListener TCP_Serveur =
new TcpListener(Port);
//TCP du serveur
//Récupération du tableau contenant les IPs du serveur (normalement une seule)
IPAddress[] Tableau_IP = (Dns.GetHostByName(Dns.GetHostName())).AddressList;
TcpClient TCP_Client;
// TCP du client
NetworkStream NS;
Client[] Clients=
new Client[50];
//Création d'un tableau de client
int Numero_Client = 0;
TCP_Serveur.Start();
//Lancement du TCP du serveir
Console.WriteLine("Serveur démarré sur {0}:{1}",Tableau_IP[0],Port);



while(
true)
{

//On attend la connexion d'un client
TCP_Client = TCP_Serveur.AcceptTcpClient();
NS = TCP_Client.GetStream();

//Création du client connecte
Clients[Numero_Client]=
new Client(Numero_Client,NS);

//Lancement d'un thread client
Thread T =
new Thread(
new ThreadStart(Clients[Numero_Client].Ecouter));
T.Start();
Numero_Client++;
}
}
}
}

Je pensais que le pb venait du fait que je fasse un nouveau new alors que g déjà créé le tableau, mais si je le fais pas, il compile pas !!!

Merci pour vos réponses

Billou_13
Bask En Force

29 réponses

MorpionMx Messages postés 3466 Date d'inscription lundi 16 octobre 2000 Statut Membre Dernière intervention 30 octobre 2008 57
3 févr. 2005 à 19:19
Si tu penses que c'est le tableau qui gene, utilises plutot un Arraylist, pour lequel tu utiliseras la méthode Add().
Well, sinon, je vais essayer de regarder ca plus en profondeur.



a++
Mx
3
TheSaib Messages postés 2368 Date d'inscription mardi 17 avril 2001 Statut Modérateur Dernière intervention 26 décembre 2007 23
4 févr. 2005 à 11:49
Tu crées des evenements

public delegate void MessageReceptionEventHandler(Object sender, EventArgs e);

public event MessageReceivedEventHandler MessageRecevived;

Tu abonnes tes clients à cette fonctions que tu déclares dans ta classe principale

ex :

Quand tu crées un nouveau client dans ta classe:

monclient.MessageRecevived += new MessageReceptionEventHandler(this.TraiteMessage);

LA fonction traitemessage sera lancé a chaque fois qu'un client recevra un message, donc tu y fait ce que tu veux

J'espere avoir été un peu clair

PS : il me saoule ce Richtextbox
::|The S@ib|::
MVP C#.NET
3
TheSaib Messages postés 2368 Date d'inscription mardi 17 avril 2001 Statut Modérateur Dernière intervention 26 décembre 2007 23
4 févr. 2005 à 11:51
Il faut que tu dises aussi quand cet evenement est declanché, dans les fonctions d'ecoute tu rajoute (si l'ecoute est dans le client)

MessageRecevived(this,"le message");

::|The S@ib|::
MVP C#.NET
3
MorpionMx Messages postés 3466 Date d'inscription lundi 16 octobre 2000 Statut Membre Dernière intervention 30 octobre 2008 57
3 févr. 2005 à 19:56
J'ai testé ton code, ouvert une dizaine de clients qui envoient en
boucle le meme message chaque seconde, et sincérement, j'ai pas de
ramage :/

La seule modification que j'ai fait, c'est que dans la classe Serveur,
j'ai sorti du Main() tout le code pour le mettre dans un constructeur,
juste parce que ca fait plus beau. Mais ca m'étonnerait beaucoup que ce
soit le probleme. Et aussi, j'ai changé l'addresse du serveur par
127.0.0.1 pour tester.



D'ailleurs, il serait préférable que tu fasses ceci :



TcpListener TCP_Serveur = new TcpListener(Tableau_IP[0], Port);



Car le constructeur que tu utilises pour le TCPListener est dépréciée dans la version 1.1 du framework



Sinon, y'a rien de spécial il me semble

Comment interviennent tes "ramages" ? Comment se font-ils ressentir ?


Mx
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
billou_13 Messages postés 860 Date d'inscription jeudi 4 mars 2004 Statut Membre Dernière intervention 19 août 2014 29
3 févr. 2005 à 20:09
Merci beaucoup a toi !!!

Ca fait deux fois que tu répond a mes questions, si tu continues, les autres vont se plaindre !!!
En tout cas, merci beaucoup de t'être mis sur mon code, j'espère que c'était pas trop chiant !
Pour tes suggestions, je les met en oeuvre de suite.

En fait, je développe sur le serveur d'une société, donc je pense que c les programmes du serveur qui font ramer. Faudrait que je teste sur mon ordi .
Ce que je trouve bizarre, c que on doit créer un new tableau de 50 objets et apres on doit recréer un new objet des qu'on créé un client, c'est pas ANORMAL ca ??? (je croyais que c'etait ca qui fesait ramer)

Et une ptite question, est ce qu'on peut créé un tableau d'objet dynamique ???

Merci a toi en tout cas pour tout ce que tu as fait pour moi (et surement pour les autres)

Bonne soirée

Billou_13
Bask En Force
0
MorpionMx Messages postés 3466 Date d'inscription lundi 16 octobre 2000 Statut Membre Dernière intervention 30 octobre 2008 57
3 févr. 2005 à 20:39
Pour ce qui est du tableau d'objet dynamique, c'est a ca que sert
l'ArrayList (tu n'es pas obligé de spécifier le nombre d'objets que tu
auras dedans )



et pour ta question sur la recreation d'un objet apres la creation d'un
tableau de 50 objets, le bout de code qui suit revient au meme, et ca
te semblera peut etre plus clair



Client[] Clients=new Client[50]; // La tu alloues de la mémoire pour 50 objets de type Client

...



Client c = new Client(Numero_Client,NS); // puis tu crées un client
Clients[Numero_Client] = c; // que tu inséres dans le tableau


Ce que tu fais en faisant Clients[Numero_Client]= new
Client(Numero_Client,NS); est une version contractée des 2
dernieres lignes de l'exemple



Bon courage et bonne soirée a toi aussi

Tiens nous au courant.


Mx
0
billou_13 Messages postés 860 Date d'inscription jeudi 4 mars 2004 Statut Membre Dernière intervention 19 août 2014 29
3 févr. 2005 à 20:59
Oki, g compris, je croyais que qd je fesais :
Client[] Clients=new Client[50];
je créé déjà mes objets
, donc je trouvais bizarre de créé des objets par la suite. Mais g compris la maintenant, en fait, tu créé que l'emplacement pour le tableau.

Merci, par contre, en ce qui concerne les ArrayList, g essayer et je n'arrive pas à le faire !
ArrayList Clients = new ArrayList,
ca marche mais après je peux pas insérer des objets, il me dit que c pas compatible. Alors je vois pas trop la syntaxe.

Je v tester alors, en tout cas merci a toi pour ton aide, je te tiendrais au courant !

PS: arrête de répondre aussi vite, je suis plus lol (j'déconne, merci beaucoup de répondre aussi vite !!!)

Bonne soirée, moi je vais essayer de faire de la place sur mon ordi pour installer Visual Studio 2003. Mais ca craint, je ve pas effacer HL² LOL, c un compromis !

@+

Billou_13
Bask En Force
0
MorpionMx Messages postés 3466 Date d'inscription lundi 16 octobre 2000 Statut Membre Dernière intervention 30 octobre 2008 57
3 févr. 2005 à 21:14
Pour ajouter ton objet a un Arraylist, tu fais juste tonArrayList.Add(tonObjet);

A priopri, y'a pas de souci. Ce qui donne :

ArrayList Clients=new ArrayList();



...

//Création du client connecte

Client c = new Client(Numero_Client,NS);

Clients.Add(c);

//Lancement d'un thread client

Thread T = new Thread(new ThreadStart(c.Ecouter));

Mx
0
billou_13 Messages postés 860 Date d'inscription jeudi 4 mars 2004 Statut Membre Dernière intervention 19 août 2014 29
3 févr. 2005 à 21:18
ok je fesais pas comme ca !!!
Merci beaucoup, je v mettre ca en place dès demain.

Bonne soirée, je v installer Visual Studio sur mon ordi, g trouver de la place ( sans virer HL² LOL)

A demain, je te tiens au courant !!!!

Billou_13
Bask En Force
0
MorpionMx Messages postés 3466 Date d'inscription lundi 16 octobre 2000 Statut Membre Dernière intervention 30 octobre 2008 57
3 févr. 2005 à 21:24
a+, et bon courage. (Et merci d'avoir epargné Gordon, il a deja assze souffert le pauvre ^^ )

Mx
0
TheSaib Messages postés 2368 Date d'inscription mardi 17 avril 2001 Statut Modérateur Dernière intervention 26 décembre 2007 23
4 févr. 2005 à 09:40
Plus rapide qu'une arraylist , utilise une hastable

::|The S@ib|::
MVP C#.NET
0
MorpionMx Messages postés 3466 Date d'inscription lundi 16 octobre 2000 Statut Membre Dernière intervention 30 octobre 2008 57
4 févr. 2005 à 09:59
C'est vrai que dans ce cas la, le HashTable pourrait aussi etre
pratique, comme ca tu pourrais retrouver n'importe quel objet client a
partir de son numéro (qui servirait de clé).

Et puis si c'est plus rapide, alors ce serait impec ^^

Mx
0
billou_13 Messages postés 860 Date d'inscription jeudi 4 mars 2004 Statut Membre Dernière intervention 19 août 2014 29
4 févr. 2005 à 10:01
Merci les gars , je vais tester de suite !

Billou_13
Bask En Force
0
billou_13 Messages postés 860 Date d'inscription jeudi 4 mars 2004 Statut Membre Dernière intervention 19 août 2014 29
4 févr. 2005 à 11:05
G fais ce que vous m'avez dit: g utiliser Hashtable et ca marche, merci !

Hashtable Clients = new Hashtable();



Client c = new Client(Numero_Client,NS);

Clients.Add(c,Numero_Client);





Seulement j'aimerais savoir comment parcourir tous mes objets et
envoyer un message a chacun ( une fois qu'un client se connecte par
exemple !) Je batailles dessus et je trouve pas comment accèder à ma
fonction envoi a partir de la Hashtable.



je pense avec un foreach() mais après je c pas trop quoi mettre



Merci d'avance,


Billou_13
Bask En Force
0
TheSaib Messages postés 2368 Date d'inscription mardi 17 avril 2001 Statut Modérateur Dernière intervention 26 décembre 2007 23
4 févr. 2005 à 11:19
un foreach (plus lent qu'un for ou un decalage de bit) sur le values de ta HashTable

foreach(object o in hash.Values)

::|The S@ib|::
MVP C#.NET
0
billou_13 Messages postés 860 Date d'inscription jeudi 4 mars 2004 Statut Membre Dernière intervention 19 août 2014 29
4 févr. 2005 à 11:20
Merci je teste !!! et je te dis


Billou_13
Bask En Force
0
MorpionMx Messages postés 3466 Date d'inscription lundi 16 octobre 2000 Statut Membre Dernière intervention 30 octobre 2008 57
4 févr. 2005 à 11:20
Deja, a ta place je mettrais :



Clients.Add(Numero_Client, c) ;

(Numéro_client est ta clé, c est ton object).



Comme ca, si tu veux acceder au client 3, tu auras juste a faire



Client c = (Client)Clients[3]



Autrement, pour ta question d'envoyer un message a tout le monde , je
pense que ceci marche (je peux pas tester pour etre sur, mais a priori
y'a pas de souci)



foreach(client c in Clients)

c.Envoyer(tonMessage);



Et si le foreach marche pas, tu utilises une boucle for basique, et tu recupere tes clients avec l'exemple un peu plus haut.



a++

Mx
0
billou_13 Messages postés 860 Date d'inscription jeudi 4 mars 2004 Statut Membre Dernière intervention 19 août 2014 29
4 févr. 2005 à 11:26
Ca marche pas, il me propose pas mieux !

J'ai aussi teste avec:

foreach(object o in Clients.Keys) //car les objets sont dans la key non ?

{

o. // et la il me propose Equals, GetHashCode, Gettype ,
Tostring alors que c'est un object de ma table et je veux utiliser la
méthode de l'object Envoyer (pour envoyer un message a tout le monde).
Avec Values c la même chose.

o.Envoyer("nouveau client entré")

}



Désolé,

Billou_13
Bask En Force
0
billou_13 Messages postés 860 Date d'inscription jeudi 4 mars 2004 Statut Membre Dernière intervention 19 août 2014 29
4 févr. 2005 à 11:28
oki je teste Mx

Billou_13
Bask En Force
0
TheSaib Messages postés 2368 Date d'inscription mardi 17 avril 2001 Statut Modérateur Dernière intervention 26 décembre 2007 23
4 févr. 2005 à 11:31
Non les clés sont les identifiants , les objets sont dans values

::|The S@ib|::
MVP C#.NET
0