Journal Server chat

Posté par  .
Étiquettes : aucune
0
15
déc.
2003
/**
* Chat avance java cote serveur
* 12/11/2003
* Remi Wipliez && Raphael Mariage.
* version 1.0
* La classe comprend le main et la definition des Threads, un thread par client
*/

import java.io.BufferedReader;
import java.io.InputStreamReader;

import java.net.DatagramSocket;
import java.net.DatagramPacket;
import java.net.InetAddress;

import java.util.Hashtable;
import java.util.StringTokenizer;
import java.lang.Thread;
import java.util.Enumeration;
import java.util.Vector;
import java.util.GregorianCalendar;

/* l'objet info_client contient toutes les informations "vitales" pour l'identification du client, c'est a dire qu'a chaque client est
* associe un objet Info-client avec tous ces parametres */
class Info_client {
int portcl;
String nick, passwd, groupe;
InetAddress adrcl;
boolean connect;
int cantalk=0, grade=0;

public Info_client(String nickname, String pass, InetAddress adr, int port, boolean connexion, int compteur, int grad) {
nick = nickname;
adrcl = adr;
portcl = port;
passwd = pass;
connect = connexion;
cantalk = compteur;
grade = grad;
}
}

class Group {
String nom, proprio;
Vector membres;

public Group(String name, String creat, Vector members) {
nom = name;
proprio = creat;
membres = members;
}
}

public class ServerUDP {

static int ind1, lg, serv_port, max_cl = 30, taille_buff = 10240, ind=0, cl_port, dest_port, k=0, port2;
static String serv_address, serv_port_tmp, chaine, ligne, adr="", login="", mess_recu="0", date, time, sepa, cmde="", line, pass, fonction;
static String renvoi_exit, user, renvoi, argu="", commande="", argument="", message="", cl, passwd="", cle, port="", nouveaucl, passcrypte;
static String[] info = new String[2];
static char tiret;
static Hashtable table_clients = new Hashtable(), table_groupes = new Hashtable();
static DatagramPacket dp, dpmdp, dpok, dpbadlog, dpexist;
static DatagramSocket ds;
static byte buffer[] = new byte[taille_buff];
static StringTokenizer str_tok, infos;
static InetAddress adr_cl, adr_dest, cl_adr, ia;
static Info_client info_cl, desti, client_t, recup, stock, majinfo, obj_exit;
static boolean pres = false, test=true, connect;
static Enumeration listekeys;
static BufferedReader br;
static Vector client = new Vector();


public static void main(String [] args) {

/* detection d'arguments passes en ligne de commande */
lg = args.length;
if (lg > 0) {
for (int i=0;i<lg;i++)
if (args[i].charAt(0) == '-') {
try {
switch(args[i].charAt(1)) {
case 'p': {
serv_port = Integer.parseInt(args[i+1]);
break;
}
default:{
System.out.println("Option inconnue : " + args[i]);
System.out.println("Options possibles : ");
System.out.println("-p : definir un port ");
System.out.println(args[i].charAt(1));
System.out.println(args[i+1]);
System.exit(0);
}
}
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println("Argument manquant...");
System.exit(0);
}
}
}
else {
serv_port = 2222;
}
/* fin de la detection des arguments */

table_clients = ControlServer.set_table_clients();
table_groupes = ControlServer.setgroups();

/* creation d'un socket avec le port du server */
ds = ConnectUDP.dsocket(serv_port);
dp = ConnectUDP.dpacket(buffer, taille_buff, null, 0);

/* lancement d'un thread dit de controle, c'est a dire permettant le controle local du server (afficher la table, la remettre a 0,
* kick un client, ... */
new Control(table_clients, ds);

/* boucle infinie de detection d'un nouveau client */
while(true && !mess_recu.equals("")) {

/* on recupere la chaine envoyee par le client */
mess_recu = ConnectUDP.recep(ds, dp);
str_tok = new StringTokenizer(mess_recu,"@");

/* recuperation des informations client : login, InetAddress et port*/
login = "";
cl_port = dp.getPort();
cl_adr = dp.getAddress();
try {
login = str_tok.nextToken();
sepa = str_tok.nextToken();
cmde = str_tok.nextToken();
}
catch(java.util.NoSuchElementException j) {
}

/*on teste la presence du client ds la table clients*/
boolean estpres = table_clients.containsKey(login);

/* s'il est present, c'est qu'il s'est deja identifie au moins une fois */
if (estpres) {
recup = (Info_client)table_clients.get(login);
passcrypte = recup.passwd;

/* s'il n'est pas connecte (c'est a dire la variable connect de l'objet Info-clients = 0*/
if (!recup.connect) {

/* s'il y a un mot de passe, c'est que ke client s'est deja identifie */
if (!recup.passwd.equals("")) {

/* si le debut du pass = new, c'est qu'un nouveau client n'a pas encore confirme son nouveau pass */
if (!recup.passwd.substring(0,3).equals("new")) {

/* le client n'est pas connecte (booleen connecte = false) */
if (!recup.connect) {

/* si le port = 0, c'est une reconnexion */
if (recup.portcl == 0) {

/* on place donc le nouveau port et la nouvelle adresse dans l'objet client */
recup.adrcl = cl_adr;
recup.portcl = cl_port;
buffer = new byte[taille_buff];
fonction = "mdp";
buffer = fonction.getBytes();
dpmdp = ConnectUDP.dpacket(buffer, buffer.length, cl_adr, cl_port);
ConnectUDP.envoi(ds, dpmdp, cl_adr, cl_port);
}

/* si le port est different de 0, c'est que le client a demande a se connecter
* et il vient de rentrer son mot de passe */
else {

/* si le mot de passe est correct, on connecte le client en passant la variable connect
* a true */
if (recup.passwd.equals(cmde)) {
recup.connect = true;

/* la variable cantalk indique quand le client a totalement fini de s'identifier
* 0 = jamais parle
* 1 = a rentre son login
* 2 = a rentre son login et son mot de passe et peut maintenant discuter sur le chat. */
recup.cantalk = 1;
buffer = new byte[taille_buff];
fonction = "ok";
buffer = fonction.getBytes();
dpok = ConnectUDP.dpacket(buffer, buffer.length, cl_adr, cl_port);
ConnectUDP.envoi(ds, dpok, cl_adr, cl_port);

/* on a accepte le client, on lui a envoye "ok" donc on peut l'ajouter a la bdd */
table_clients.remove(login);
table_clients.put(recup.nick, recup);
}

/* sinon on envoie un signe comme quoi le pass est faux */
else {
buffer = new byte[taille_buff];
fonction = "badpass";
buffer = fonction.getBytes();
dpok = ConnectUDP.dpacket(buffer, buffer.length, cl_adr, cl_port);
ConnectUDP.envoi(ds, dpok, cl_adr, cl_port);
}
}
}
}

/* ici, si le debut du pass est new, c'est ke le client vient d'envoyer sa confirmation de mdp */
else {

/* si les 2 pass sont egaux on valide, et on ajoute le client a la table et on le connecte */
String passtmp = recup.passwd;
String passtmp2 = passtmp.substring(3, passtmp.length());
if (passtmp2.equals(cmde)) {
recup.passwd = cmde;
recup.connect = true;
recup.cantalk=1;
fonction = "ok";
buffer = fonction.getBytes();
dpok = ConnectUDP.dpacket(buffer, buffer.length, cl_adr, cl_port);
ConnectUDP.envoi(ds, dpok, cl_adr, cl_port);
table_clients.remove(login);
table_clients.put(recup.nick, recup);

/* mise a jour du fichier, c'est a dire rajoute une ligne contenant le login et le
* mot de passe du nouveau client */
ControlServer.exec("maj", ds);
}

/* si les 2 pass sont differents, le client s'est trompe on redemande */
else {
recup.passwd = "";
fonction = "bad2pass";
buffer = fonction.getBytes();
dpok = ConnectUDP.dpacket(buffer, buffer.length, cl_adr, cl_port);
ConnectUDP.envoi(ds, dpok, cl_adr, cl_port);
}
}
}

/* si le mdp est nul, c'est un nouveau client qui vient d'entrer son 1er pass */
/* on lui envoie donc la demande de second mdp */
else {
recup.passwd = "new" + cmde;
fonction = "2ndpass";
buffer = fonction.getBytes();
dpok = ConnectUDP.dpacket(buffer, buffer.length, cl_adr, cl_port);
ConnectUDP.envoi(ds, dpok, cl_adr, cl_port);
}
}

/* si le client est deja connecte */
else {

/* si le port du client demandeur est different de celui enregistre dans la table (pour le client du
* meme nom), c'est qu'il existe deja un client connecte avec ce login */
if (recup.portcl != cl_port) {
fonction = "connected";
buffer = fonction.getBytes();
dpok = ConnectUDP.dpacket(buffer, buffer.length, cl_adr, cl_port);
ConnectUDP.envoi(ds, dpok, cl_adr, cl_port);

/* creer un paquet null pour mettre a zero toutes les nouvelles infos, car le client qui a declenche ce message
* (connected) ne PEUT pas se connecter */
recup = new Info_client("", "", null, 0, false, 0, 0);
}

/* si les 2 ports sont egaux, c'est le bon client */
else {

/* si le debut du pass est egal a old, le client vient de donner son ancien mot de passe */
if (recup.passwd.substring(0,3).equals("old")) {

/* l'ancien mot de passe est egal a celui rentre : on demande le nouveau */
if (recup.passwd.substring(3,recup.passwd.length()).equals(cmde)) {
fonction = "newpass1";
buffer = fonction.getBytes();
dpok = ConnectUDP.dpacket(buffer, buffer.length, cl_adr, cl_port);
ConnectUDP.envoi(ds, dpok, cl_adr, cl_port);
recup.passwd = "vachanger";
recup.cantalk = 0;
}
else {
fonction = "badoldpass";
System.out.println("ancien = " + recup.passwd.substring(3,recup.passwd.length()));
System.out.println("new = " + cmde);
buffer = fonction.getBytes();
dpok = ConnectUDP.dpacket(buffer, buffer.length, cl_adr, cl_port);
ConnectUDP.envoi(ds, dpok, cl_adr, cl_port);
}
}

/* si le mot de passe ne commence pas par old, soit il n'y a rien soit il est nul pour un changement */
else {

/* si le debut du pass est nul, le client vient de donner son nouveau mot de passe */
if (recup.passwd.equals("vachanger")) {
recup.passwd = "";
fonction = "newpass2";
buffer = fonction.getBytes();
dpok = ConnectUDP.dpacket(buffer, buffer.length, cl_adr, cl_port);
ConnectUDP.envoi(ds, dpok, cl_adr, cl_port);
recup.passwd = "new" + cmde;
}

/* si le debut du pass est "new", le client vient de donner sa confirmation de nouveau mot de passe */
else {
if (recup.passwd.substring(0,3).equals("new")) {

/* les 2 nouveaux pass sont egaux, on procede alors au changement du pass */
if (recup.passwd.substring(3,recup.passwd.length()).equals(cmde)) {
fonction = "newpass";
buffer = fonction.getBytes();
dpok = ConnectUDP.dpacket(buffer, buffer.length, cl_adr, cl_port);
ConnectUDP.envoi(ds, dpok, cl_adr, cl_port);
recup.passwd = cmde;
recup.cantalk=1;
}

/* les 2 nouveaux pass sont differents, ont ne peut proceder au changement et on remet l'ancien*/
else {
fonction = "badnewpass";
buffer = fonction.getBytes();
dpok = ConnectUDP.dpacket(buffer, buffer.length, cl_adr, cl_port);
ConnectUDP.envoi(ds, dpok, cl_adr, cl_port);
recup.passwd = "old" + passcrypte;
}
}
}
}
}
}
}

/* si le login n'est pas present, on teste si c'est un client qui veut s'identifier pour la 1ere fois
* avec le mot cle new + login. Sinon c'est une erreur de frappe sur le login ou il n'existe pas (encore)*/
else {
if (login.equals("new")) {

/* on verifie ici que le nouveau login entre n'est pas deja utilise */
boolean exist = table_clients.containsKey(cmde);
if (!exist) {

/* les conditions remplies, on peut creer un nouvel objet avec l'adr du client, son port, la variable connect a false
* la variable cantalk a 0, et un pass vierge car il n'en a encore rentre aucun */
info_cl = new Info_client(cmde, "", cl_adr, cl_port, false, 0,0);
table_clients.put(info_cl.nick, info_cl);

// penser ici a mettre le fichier client a jour
buffer = new byte[taille_buff];
fonction = "mdp";
buffer = fonction.getBytes();
dpmdp = ConnectUDP.dpacket(buffer, buffer.length, cl_adr, cl_port);
ConnectUDP.envoi(ds, dpmdp, cl_adr, cl_port);
}

/* si le login existe, on envoie un message au client */
else {
buffer = new byte[taille_buff];
fonction = "exist";
buffer = new byte[taille_buff];
buffer = fonction.getBytes();
dpexist = ConnectUDP.dpacket(buffer, buffer.length, cl_adr, cl_port);
ConnectUDP.envoi(ds, dpexist, cl_adr, cl_port);
recup = new Info_client("", "", null, 0, false, 0,0);
}
}

/* si le login n'est pas new le login est mauvais */
else {
buffer = new byte[taille_buff];
fonction = "badlog";
buffer = new byte[taille_buff];
buffer = fonction.getBytes();
dpbadlog = ConnectUDP.dpacket(buffer, buffer.length, cl_adr, cl_port);
ConnectUDP.envoi(ds, dpbadlog, cl_adr, cl_port);
recup = new Info_client("", "", null, 0, false, 0,0);
}
}
/*******************************************/
// fin de la procedure de detection client
//TestClient(login, cl_adr, cl_port);

GregorianCalendar day = new GregorianCalendar();


/* dans chaque ojbet client, la variable cantalk est passe a 2 apres un 1er passage ici, pour etre sur que le pass ou des infos
* de connection ne s'affiche */
if (recup.cantalk == 2) {

/* on teste si le client veut sortir ou pas */
if (cmde.equals("/exit")) {
date = day.getTime().toString();
time = date.substring(11,20);
renvoi_exit = login + " has exit at " + time;
System.out.println(renvoi_exit);
buffer = renvoi_exit.getBytes();

/* creation d'un nouveau packet avec la chaine a renvoyer */
dp = ConnectUDP.dpacket(buffer, buffer.length, null, 1);


/* boucle qui envoit la chaine annoncant la sortie d'un client a chacun des clients connectes */
listekeys = table_clients.keys();
for (ind=0; ind<table_clients.size(); ind++) {
cle = (String)listekeys.nextElement();
desti = (Info_client)table_clients.get(cle);
adr_dest = (InetAddress)desti.adrcl;
dest_port = desti.portcl;
if (dest_port != 0)
ConnectUDP.envoi(ds, dp, adr_dest, dest_port);
}
/* on enleve le client de la bdd info_client */
table_clients.remove(login);
obj_exit = new Info_client(login, recup.passwd, null, 0, false, 0,0);
table_clients.put(obj_exit.nick, obj_exit);

}

/* dans les autres cas, un message normal ou une commande */
else {

/* ne rien faire si la chaine envoyee est nulle */
if (!cmde.equals("")) {

/* test afin de reconnaitre une commande a l'aide du caracteres / (slash) */
if (cmde.charAt(0) != '/') {
System.out.println(login + "> " + cmde);
date = day.getTime().toString();
time = date.substring(11,20);
renvoi = time + " " + login + "> " + cmde;
buffer = renvoi.getBytes();
dp = ConnectUDP.dpacket(buffer, buffer.length, null, 1);

/* c'est un message normal donc on l'envoie a tout le monde */
listekeys = table_clients.keys();
for (int i=0; i<table_clients.size(); i++) {
cle = (String)listekeys.nextElement();
desti = (Info_client)table_clients.get(cle);
login = desti.nick;
adr_dest = desti.adrcl;
dest_port = desti.portcl;
if (dest_port != 0)
ConnectUDP.envoi(ds, dp, adr_dest, dest_port);
}
}

/* il s'agit ici du traitement de la chaine de caracteres contenant l'intitule de la
* commande, le ou les arguments, le login de l'expediteur et le message */
else {
try {
k=0;
/* chaque "partie" (login, argument(s), commande,...)est separee par un espace.
* Ainsi on a 3 boucles while qui recupere chacun des parametres. Puis on reduit
* au fur et a mesure les chaines avec substring jusqu'a obtenir les 3 parametres
* dans des chaines separees */
while(cmde.charAt(k) != ' ') {
commande = commande + cmde.charAt(k);
k++;
}
argu = cmde.substring(k+1,cmde.length());
k=0;
while(argu.charAt(k) != ' ') {
argument = argument + argu.charAt(k);
k++;
}
message = argu.substring(k+1, argu.length());

/* ensuite on lance l'interpretation de la commande */
Cmde.traitement(ds, login, commande, argument, message);
}
catch(java.lang.StringIndexOutOfBoundsException e) {
if (commande.equals("/msg")) {
System.out.println("usage de /msg : ");
System.out.println("/msg dest message");
System.out.println("/msg dest1+dest2+dest3... message");
}
else {
Cmde.traitement(ds, login, commande, argument, message);
login = "";
commande = "";
argument = "";
message = "";
}
}
message = "";
argu = "";

}
}
/* creation d'un nouveau paquet vierge pour reception */
buffer = new byte[taille_buff];
dp = ConnectUDP.dpacket(buffer, taille_buff, null, 1);
}
}
if (recup.cantalk == 1)
recup.cantalk = 2;
}
}
}

/* Thread d'attente d'entree au clavier pour la gestion interne du serveur (commande, sortie, kick, ...) */
class Control extends Thread {

DatagramSocket ds;
DatagramPacket dp;
int taille_buff = 10240, sport, test2;
String adrs, serv_quit, command="", test1, cle, kicke;
InetAddress S_ia;
Hashtable info;
BufferedReader kbr;
byte[] buffer = new byte[taille_buff];
Info_client desti, test;
int dest_port;
InetAddress adr_dest, test3;
Enumeration listekeys;

public Control(Hashtable tbl, DatagramSocket sock) {
info = tbl;
ds = sock;
start();
}

public void run() {

/* boucle infinie qui attend les entrees clavier sur le serveur */
while(true) {
System.out.print("/");
kbr = new BufferedReader(new InputStreamReader(System.in));
try {
command = kbr.readLine();
}
catch(java.io.IOException e) {
System.out.println("erreur IO");
}
ControlServer.exec(command, ds);
}
}
}
  • # Re: Server chat

    Posté par  (site web personnel) . Évalué à 4.

    Oui chat avance (comme vous dites en haut de votre chourse) mais chat cherait vachement mieux chi vous trouviez un cherveur pour chtoquer chat, parche que le balancher comme chat chur LinuxFr dans un pauvre journal de chegonde jone, chat fait un peu naje.
    • [^] # Re: Server chat

      Posté par  . Évalué à 3.

      le balancher comme chat chur LinuxFr dans un pauvre journal de chegonde jone, chat fait un peu naje.

      Nan, pas si naje que cha, parche que on peut croire qu'ils veulent nous lancher un message... et alors amuche toi bien à analicher le code, du déchut jusqu'à la chin !

      (une boucheille à la mer... mocherne !)
  • # super intéressant

    Posté par  . Évalué à 0.

    ...

    ça y est t'as bien joué ? t'as découvert les journaux ?

    en plus Java ça pue spa libre...
    • [^] # Re: super intéressant

      Posté par  . Évalué à 1.

      Woooh oki oki, dsl je decourvrais les journaux, j'avais kca a dispo .... =)
      Si tu veux tout savoir, j'ai ecrit aux admins histoire de savoir si CT possible de virer les journaux..

      C tt, fo pas s'enflammer pour si peu..

      PS : si vous voulez le server java correspondant au client + haut...

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.