billou_13
Messages postés860Date d'inscriptionjeudi 4 mars 2004StatutMembreDernière intervention19 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();
}
//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 !!!
MorpionMx
Messages postés3466Date d'inscriptionlundi 16 octobre 2000StatutMembreDernière intervention30 octobre 200857 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.
MorpionMx
Messages postés3466Date d'inscriptionlundi 16 octobre 2000StatutMembreDernière intervention30 octobre 200857 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
Vous n’avez pas trouvé la réponse que vous recherchez ?
billou_13
Messages postés860Date d'inscriptionjeudi 4 mars 2004StatutMembreDernière intervention19 août 201429 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)
MorpionMx
Messages postés3466Date d'inscriptionlundi 16 octobre 2000StatutMembreDernière intervention30 octobre 200857 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
billou_13
Messages postés860Date d'inscriptionjeudi 4 mars 2004StatutMembreDernière intervention19 août 201429 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 !
MorpionMx
Messages postés3466Date d'inscriptionlundi 16 octobre 2000StatutMembreDernière intervention30 octobre 200857 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 ^^
billou_13
Messages postés860Date d'inscriptionjeudi 4 mars 2004StatutMembreDernière intervention19 août 201429 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
MorpionMx
Messages postés3466Date d'inscriptionlundi 16 octobre 2000StatutMembreDernière intervention30 octobre 200857 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.
billou_13
Messages postés860Date d'inscriptionjeudi 4 mars 2004StatutMembreDernière intervention19 août 201429 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.