TCP chat server/client

TCP chat server/client - Java - Programmation

Marsh Posté le 23-09-2006 à 15:05:58    

J'essaye de me créer un petit chat en java
Je me suis fait une classe chat (mon main, qui décidera de lancer un serveur ou un client), une chatserver et une chatclient
 
pour pouvoir accepter plusieurs clients, je pense donc multithreadé mon serveur. Mon questionnement vient plutot sur: lorsque le client 1 enverra un message au serveur, celui ci devra le forwarder au client 2-3-4... mais pas au 1er
 
et vu que chaque client sera dans son thread, qu'elle serait la meilleure facon de procédé
 

Reply

Marsh Posté le 23-09-2006 à 15:05:58   

Reply

Marsh Posté le 23-09-2006 à 19:04:07    

up

Reply

Marsh Posté le 24-09-2006 à 02:05:11    

sur ton programme serveur, t'as pas un p'tit truc qui reference tous les clients connectés?


---------------
Mon feedback
Reply

Marsh Posté le 24-09-2006 à 11:19:07    

gocho a écrit :

sur ton programme serveur, t'as pas un p'tit truc qui reference tous les clients connectés?


+1.
Quand il cree son Thread, il le met dans un array  et après il recupère tous les threads qui l'interesse au moment d'envoyer le message


---------------
Si la vérité est découverte par quelqu'un d'autre,elle perd toujours un peu d'attrait
Reply

Marsh Posté le 24-09-2006 à 16:13:16    

sinon pour faire un chat pas mal, c'est le multicast.  
ça envoie automatiquement les messages à tous le groupe. Pas besoin de point central.  
 
sinon, on peut imaginé un serveur qui est multithreadé. dans chaque message qu'il reçoit, il à un id du destinataire (et de la source). Puis il se charge de le renvoyer.  
Chaque client doit donc posséder un thread de réception qui affichera donc le message sur l'écran. Comme le message comprend les infos de la source il peut savoir de qui ça vient.  
 
C'est vraiment facile à faire

Reply

Marsh Posté le 25-09-2006 à 06:04:50    

gocho a écrit :

sur ton programme serveur, t'as pas un p'tit truc qui reference tous les clients connectés?


 
je m'étais basé sur ce tuto pour commencé:
 
http://java.sun.com/developer/onli [...] ocket.html
 
il ne place pas le thread dans un array justement, et le programme principal est bloquant sur la méthode accepte
 
jvais regardé du coté du multicast

Reply

Marsh Posté le 27-09-2006 à 17:17:44    

un petit up, jcrois pas utiliser le multicast, jvais revenir avec mon serveur multithreadé
 
en gros, chaque fois qu'un client envoit un message, il faut que ca passe par le serveur et que ca soit envoyé à tous les clients sauf celui qui l'avait envoyé au départ

Reply

Marsh Posté le 27-09-2006 à 17:54:01    

atta, que je comprenne bien.
Tu as un seul programme qui fait soit client, soit serveur?
Ou tu as deux fichiers distincts avec dans l'un un client, et dans l'autre un serveur?
 
sinon, en fait, dans ton programme serveur tu cree une structure (tableau par exemple) dans lequel tu vas mettre tous les ids des clients lorsqu'ils vont se connecter.
Ensuite lors de l'envoi du message, tu n'a qu'a envoyer le message a tous les clients du tableau, sauf celui dont l'id correspond à l'id qui a emis le message


---------------
Mon feedback
Reply

Marsh Posté le 27-09-2006 à 19:27:46    

ca ressemble pas mal à ca
 
mon problème: comment séparer mes threads?
le serveur doit avoir 1 thread par connexion client. Ces thread s'occupe de recevoir les messages des clients, mais est-ce ceux-ci qui itéreront ma liste de clients pour envoyer un message?

Reply

Marsh Posté le 27-09-2006 à 21:48:21    

Personellement, j'ai déjà fait un serveur en java, par contre, il n'y avait pas de dialogue ente les différents clients ce qui n'empéchait pas d'avoir des objets en comun pour toutes les conections.
J'avais divisé mon serveur comme suit :
- le thread initial qui sert à lancer les différents thread qui ne dialoguent avec aucun client et qui ensuite écoute le port sur lequel se conecte les clients. Pour chaque client qui se conecte il ouvre un thread dédié au dialogue avec ce client.
- plusieurs thread pour s'occuper de divers éléments du serveur. Pour toi, il sera préférable d'en faire au moins un pour faire suivre les messages aux autres clients sans te retrouver à perdre du temps avant de te remettre à écouter le port. Pour moi, c'était entre autre pour gérer une fille d'attente pour l'accés aux fichiers.
- un thread par conection établis afin de ne pas bloquer tout le serveur quand un client subis une déconection sauvage (liaison RTC qui tombe, coupure de courant ...)
- un thread par conection établis afin d'envoyer les messages au clients (comme ça tu peux envoyer même si tu ne recois rien du client)
 
Côté dialogue entre les thread, j'ai fait simple : je remplis un ArrayList et  l'autre thread le relis pour savoir s'il doit traiter ou attendre à nouveau et quel texte il doit traiter.
 
Erreurs à ne pas faire :  
- écouter sur un port sans timeout (ce qui bloque le thread sans possibilité de véritable détection de liaison tombé)
- utiliser des timer pour exécuter une fonction d'un thread à heure réguliére : cette fonction serait exécuté par le thread qui gére les timer (tous les timer sont géré par le même) et si l'exécution d'une fonction lancé par un timer se bloque, tous les timer se bloquent. A la place il vaut mieux mettre le thread en pause pour la durée voulut.

Reply

Marsh Posté le 27-09-2006 à 21:48:21   

Reply

Marsh Posté le 28-09-2006 à 04:20:57    

"un thread par conection établis afin de ne pas bloquer tout le serveur quand un client subis une déconection sauvage (liaison RTC qui tombe, coupure de courant ...)"
hum... jle vois pas vraiment celui-la. En quoi le plantage qu'une des connexion tcp va bloquer le serveur? Le protocol est pas déjà fait pour gérer tout ca?
 
pour le reste je suis plutot daccord
1 pour accepter les connexion
1 pour l'envoit de message
1 par connexion client qui a été accepté

Reply

Marsh Posté le 28-09-2006 à 10:03:06    

Par défaut, en java, il n'y a pas de durée de timeout de définis sur l'écoute d'un socket réseau. Et qui dit pas de durée dit durée tellement grande que ca n'est pas vivable. Si en plus t'as tout en un seul thread, alors t'es foutus à chaque déconection qui se passe mal.
Au niveau des protocoles, le protocole tcp est un protocole dit "déconecté". En clair, on ne peut être sur de la déconection que quand on essaie d'envoyer des données ou au bout d'un temps X si on est certain de recevoir réguliérement des données. Ca n'est pas pour rien que tous les serveur IRC envoyent des pings à intervalle régulier avec obliguation de réponse de la part du client.
 
Par sécurité et vu cette caractéristique intrinséque de ce protocole, j'ai séparé chaque écoute dans des threads réseau. En passant, ca a deux autres avantages :
1) ca évite de cumuler les temps d'attente relatif à chaque client conecté (si tu écoutes chaque conection pendant 1/100 éme de seconde, le temps de retard du traitement des message sera invisible pour 5 clients mais pas pour 100)
2) si un thread tombe les autres continuent à marcher tandis qu'avec un seul thread, il suffit de tomber sur une erreur pas ou mal gérer pour tout bloquer.

Message cité 1 fois
Message édité par omega2 le 28-09-2006 à 10:05:36
Reply

Marsh Posté le 30-09-2006 à 23:39:56    

comment est-ce que je fais pour arreter mon thread qui attend des connexions, le server.accept(), lorsque l'usager désire fermer le serveur?
même question pour terminer le thread qui attend l'arrivée de message sur le client, il est bloqué sur mon in.readLine()

Reply

Marsh Posté le 01-10-2006 à 02:04:09    

Pour le readline, il faut que tu définisses un timeout sur le socket ( Socket.setSoTimeout(n); )
Pour l'autre, je ne me rapelle pas mais il me semble que c'est la même chôse.

Reply

Marsh Posté le 01-10-2006 à 04:21:05    

bon toute marche pas mal comme je le veux
 
maintenant: je désire faire du ménage dans mon arraylist de client (dans la partie du Server)
je croyais qu'en vérifiant mes Socket, client.isClosed() je saurais qu'elle client s'est déconnecté mais ca semble pas être le cas (même si dans mon code client, j'ai implicitement des socket.close()
 
une idée?

Reply

Marsh Posté le 01-10-2006 à 10:02:19    

faut tjs du temps avant que la connexion se ferme (qq minutes parfois selon l'os). Essaye de voir ce que ça donne après quelques minutes...

Reply

Marsh Posté le 01-10-2006 à 15:08:44    

et comment ca tu as *implicitement* des socket.close() ?


---------------
Mon feedback
Reply

Marsh Posté le 01-10-2006 à 16:20:29    

il faut que le client puisse fermer sa connexion, alors lorsque mon client entre /quit à la console, celui-ci a un socket d'ouvert (lorsqu'il s'est connecté au serveur). J'arrête donc de lire sur le socket, et je close mon socket

Reply

Marsh Posté le 03-10-2006 à 13:02:38    

alors ca en est ou? ca marche?
Ton truc de deco fonctionne comme il faut?
Si c'est toujours pas top moumoute, tu peux vois tu cote des deco comme cela a ete suggéré, ou voir comme fait irc, des pings reguliers avec obligation de reponse.
Si ca repond pas, tu close le socket et tu vires le client de ton array

Reply

Marsh Posté le 03-10-2006 à 15:34:30    

ca semble bien fonctionner, dans le pire des cas, mon serveur traine une connexion que le client a fermé pendant un certain temps avant de la retirer

Reply

Marsh Posté le 12-10-2006 à 23:17:58    

pense a faire un thread nettoyeur ; )
 
et aussi, tu doit etablir ton protocol si c'est pas déja fait

Reply

Marsh Posté le 13-10-2006 à 16:25:21    

omega2 a écrit :

Au niveau des protocoles, le protocole tcp est un protocole dit "déconecté".


 
Euh tu es sûr de ton coup là ? Parce que j'ai toujours pensé (de ce que j'ai lu/appris) que le TCP était un protocole "connecté" par opposition à l'UDP.

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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