Ca rame sévère !

Résolu
Signaler
Messages postés
860
Date d'inscription
jeudi 4 mars 2004
Statut
Membre
Dernière intervention
19 août 2014
-
 cs_JuS -
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

Messages postés
3466
Date d'inscription
lundi 16 octobre 2000
Statut
Membre
Dernière intervention
30 octobre 2008
55
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
Messages postés
2368
Date d'inscription
mardi 17 avril 2001
Statut
Modérateur
Dernière intervention
26 décembre 2007
22
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
Messages postés
2368
Date d'inscription
mardi 17 avril 2001
Statut
Modérateur
Dernière intervention
26 décembre 2007
22
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
Messages postés
3466
Date d'inscription
lundi 16 octobre 2000
Statut
Membre
Dernière intervention
30 octobre 2008
55
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
Messages postés
860
Date d'inscription
jeudi 4 mars 2004
Statut
Membre
Dernière intervention
19 août 2014
28
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
Messages postés
3466
Date d'inscription
lundi 16 octobre 2000
Statut
Membre
Dernière intervention
30 octobre 2008
55
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
Messages postés
860
Date d'inscription
jeudi 4 mars 2004
Statut
Membre
Dernière intervention
19 août 2014
28
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
Messages postés
3466
Date d'inscription
lundi 16 octobre 2000
Statut
Membre
Dernière intervention
30 octobre 2008
55
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
Messages postés
860
Date d'inscription
jeudi 4 mars 2004
Statut
Membre
Dernière intervention
19 août 2014
28
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
Messages postés
3466
Date d'inscription
lundi 16 octobre 2000
Statut
Membre
Dernière intervention
30 octobre 2008
55
a+, et bon courage. (Et merci d'avoir epargné Gordon, il a deja assze souffert le pauvre ^^ )

Mx
Messages postés
2368
Date d'inscription
mardi 17 avril 2001
Statut
Modérateur
Dernière intervention
26 décembre 2007
22
Plus rapide qu'une arraylist , utilise une hastable

::|The S@ib|::
MVP C#.NET
Messages postés
3466
Date d'inscription
lundi 16 octobre 2000
Statut
Membre
Dernière intervention
30 octobre 2008
55
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
Messages postés
860
Date d'inscription
jeudi 4 mars 2004
Statut
Membre
Dernière intervention
19 août 2014
28
Merci les gars , je vais tester de suite !

Billou_13
Bask En Force
Messages postés
860
Date d'inscription
jeudi 4 mars 2004
Statut
Membre
Dernière intervention
19 août 2014
28
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
Messages postés
2368
Date d'inscription
mardi 17 avril 2001
Statut
Modérateur
Dernière intervention
26 décembre 2007
22
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
Messages postés
860
Date d'inscription
jeudi 4 mars 2004
Statut
Membre
Dernière intervention
19 août 2014
28
Merci je teste !!! et je te dis


Billou_13
Bask En Force
Messages postés
3466
Date d'inscription
lundi 16 octobre 2000
Statut
Membre
Dernière intervention
30 octobre 2008
55
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
Messages postés
860
Date d'inscription
jeudi 4 mars 2004
Statut
Membre
Dernière intervention
19 août 2014
28
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
Messages postés
860
Date d'inscription
jeudi 4 mars 2004
Statut
Membre
Dernière intervention
19 août 2014
28
oki je teste Mx

Billou_13
Bask En Force
Messages postés
2368
Date d'inscription
mardi 17 avril 2001
Statut
Modérateur
Dernière intervention
26 décembre 2007
22
Non les clés sont les identifiants , les objets sont dans values

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