Créer un reseau en java

Fermé
othmane19 Messages postés 96 Date d'inscription jeudi 16 avril 2009 Statut Membre Dernière intervention 27 avril 2013 - 24 oct. 2011 à 14:51
othmane19 Messages postés 96 Date d'inscription jeudi 16 avril 2009 Statut Membre Dernière intervention 27 avril 2013 - 21 nov. 2011 à 13:36
Bonjour,
Je voulais faire un programme en socket java, qui permet de créer un réseau virtuel de telle façon a ce que une machine qui exécute le programme envoie un fichier, qui passe par des machine intermédiaire exécutant eux aussi le programme avant d'arriver a la destination finale.
Le problème c'est que envoyer un fichier d'une machine a une autre s marche en spécifiant les adresse IP du client et serveur, mais entre plusieurs machine qui joueront le rôle de machine intermédiaire (routeur) pour acheminer le fichier ca j'ai aucune idée.
Je vous en pris si vous avez une idée, des pistes, bout de programme pour s'y faire aidez moi.
Et merci d'avance.
A voir également:

26 réponses

KX Messages postés 16754 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 020
24 oct. 2011 à 17:15
Tes machines intermédiaires sont des serveurs (on ne peut pas vraiment parler de routeur ici vu qu'elles doivent exécuter un programme dessus). Ces machines vont elles aussi avoir une adresse IP, donc quand tu envoies le fichier au client, c'est en fait au serveur que tu dois l'envoyer. Le serveur après avoir exécuté le programme enverra alors le programme soit au client final, soit à un autre serveur intermédiaire.
1
othmane19 Messages postés 96 Date d'inscription jeudi 16 avril 2009 Statut Membre Dernière intervention 27 avril 2013
24 oct. 2011 à 18:55
merci pour ta réponse il me semble que t bien compris le sujet mais ce que j arrive pas a comprendre c'est comment faire le relayage entre les machine par ce que les choses avec 2 machine sont plus simple en spécifiant que l'@ip source et @ip destination mais avec plusieurs machine intermédiaire ..........
et merci d'avance
0
KX Messages postés 16754 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 020
24 oct. 2011 à 19:17
Et bien en plus de transmettre le programme, tu vas transmettre l'adresse ip du client dans le contenu du message. Si la machine qui reçoit le message est le client, c'est fini, sinon elle doit avoir une table de routage pour savoir à qui (client ou serveur intermédiaire) renvoyer le message (programme+adresse ip).
Éventuellement la table de routage peut-être embarqué dans le message, c'est à dire que l'émetteur liste tous les serveurs intermédiaires par lequel le message doit passer.

Exemple :

Emetteur envoie [serveur1, serveur2, serveur3, client] au serveur1
Serveur 1 reçoit le message et envoi à serveur2 [serveur2, serveur3, client]
Serveur 2 reçoit le message et envoi à serveur3 [serveur3, client]
Serveur 3 reçoit le message et envoi à client [client]
0
othmane19 Messages postés 96 Date d'inscription jeudi 16 avril 2009 Statut Membre Dernière intervention 27 avril 2013
24 oct. 2011 à 20:52
je te remercie je pense que ce que tu dis comme principe sa peut marcher juste que j'ai peur a ce que cette solution soit nom valable dans le cas ou je doit passer a la 2etape qui est pouvoir acheminer le fichier en calculant le bon chemin dynamiquement et nom statiquement comme tu l a indiqué
j attend t réponse
merci d'avance
0
KX Messages postés 16754 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 020
24 oct. 2011 à 22:24
Statique ou dynamique, je ne suis pas sûr que ce problème intervienne dans ce que j'ai expliqué.

Dans mon exemple la liste "serveur1... client" n'est pas forcément statique. Le serveur1 peut très bien avoir construit dynamiquement ce chemin en fonction de l'état du réseau. En fait ça correspondrait à ce qu'on appelle un mode connecté. Le chemin est le même pour l'envoi de la donnée complète (ce que tu veux vu que chaque serveur doit exécuter le programme) contrairement à un mode non-connecté, où les différents paquets peuvent ne pas tous transiter par les même serveurs (ex. le début du programme va passer par Serveur2, alors que la fin passera par Serveur4)

Comme je l'ai mentionné plus haut, le chemin n'est pas obligé d'être embarqué, auquel cas, chaque serveur détermine, quand il l'a reçu, comment rediriger le message un peu plus près du destinataire.
Mais il y a différentes manières de gérées ces tables de routages, mais toutes ne sont pas dynamiques (en particulier l'administrateur d'un réseau local,peut définir lui même son mappage de manière totalement statique).

Donc statique ou dynamique, la différence n'est pas vraiment pertinente par rapport à ce que j'ai proposé, la pertinence vient quand tu cherches à savoir quel doit être le contenu de la liste (comment tu la construit au départ) et là le choix pourra être de le faire statiquement ou dynamiquement.
0
othmane19 Messages postés 96 Date d'inscription jeudi 16 avril 2009 Statut Membre Dernière intervention 27 avril 2013
24 oct. 2011 à 23:52
dnc en gros soit statique en déterminant des le départ la liste des noeud a suivre ou dynamiquement en se basant sur une valeur de métrique défini statiquement entre 2 machine afin de pouvoir choisir entre les chemin
mais franchement du faite que je suis débutant en prog socket java je vais essayer d'acheminer un message entre 2 machine en passant par un intermédiaire: client----->serveur1------>serveur je pense que déjà ca un premier pas tu pense que c 'est pas compliqué ca??
j'attende de toi si possible d'aide au niveau code
merci de ta compréhension vraiment tes message m'ont éclairé un peu le principe
merci d'avance
0
othmane19 Messages postés 96 Date d'inscription jeudi 16 avril 2009 Statut Membre Dernière intervention 27 avril 2013
25 oct. 2011 à 15:21
bon je me suis basé sur le lien que tu ma donné donc le transfert entre 2 fichier marche mais quand j'essaye d envoyer une information sup(@IP du serveur au client ) j 'arrive pas sachant que j 'ai utilisé un code qui marchait bien dans le cas d'envoi du message normal.
pou s 'y faire j'ai utilisé 2 methode sendadr pour l'envoi de l'adresse et réception pour la réception que j 'ai implémenté au niveau de la classe commun:
voici le code en espérant que tu me donne des indices pour la correction
et merci de votre compréhension

public class commun
{
static ObjectOutputStream out;
static String adr;
static ObjectInputStream in;

public static void sendadr(String adr,Socket sock) throws IOException
{

ObjectOutputStream out = new ObjectOutputStream(sock.getOutputStream());
out.flush();
in = new ObjectInputStream(sock.getInputStream());


out.writeObject(adr);
out.flush();
System.out.println("envoyééééé" + adr);


}






public static void reception() throws IOException, ClassNotFoundException
{


//reception message//
adr = (String)in.readObject();
System.out.println("recu////" + adr);

}

public static void recevoir(Socket sock) throws IOException, ClassNotFoundException
{
ObjectOutputStream out = new ObjectOutputStream(sock.getOutputStream());
out.flush();
in = new ObjectInputStream(sock.getInputStream());
while(true)
{
//reception message//
adr = (String)in.readObject();
System.out.println("adresse recu:" + adr);





}
}
0
KX Messages postés 16754 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 020
25 oct. 2011 à 17:18
Il n'y a aucune raison que out, adr et in, soient des membres static de classe alors que ce sont des variables locales ! Je regarderai ton code en détail un peu plus tard, mais l'utilisation de Object(Out/In)putStream, je ne m'en servirait que pour récupérer l'en-tête. Par exemple une List<String> qui contient les adresses IP du serveur. Mais pour la suite je traiterai le stream comme dans mon exemple de fichier.
0
KX Messages postés 16754 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 020
26 oct. 2011 à 15:17
J'ai repris mon code de transfert de fichiers pour y rajouter un en-tête.

public class Serveur
{	
	public static void main(String...args) throws IOException 
	{
		// Ouverture d'une communication
		Socket sock = new ServerSocket(Commun.port).accept();
		ObjectInputStream in = new ObjectInputStream(sock.getInputStream());
		
		// Réception de l'en-tête
		int n = in.readInt();
		
		String[] tab = new String[n];
		
		for (int i=0; i<n; i++)
			tab[i]=in.readUTF();
					
		// Réception du fichier
		Commun.transfert(
				in,
				new FileOutputStream(new File("D:\\test2.png")),
				true);
		
		// Fermeture de la communication
		sock.close();
		
		// Affichage de l'en-tête		
		for (String s : tab)
			System.out.println(s);
	} 
}

public class Client
{
	public static void main(String...args) throws IOException 
	{  
		// En-tête à envoyer
		String[] tab = {"Serveur1", "Serveur2", "Client"};
		
		// Ouverture de la communication
		Socket sock = new Socket(InetAddress.getLocalHost(),Commun.port);
		ObjectOutputStream out = new ObjectOutputStream(sock.getOutputStream());

		// Envoi de l'en-tête
		out.writeInt(tab.length);
		for (int i=0; i<tab.length; i++)
			out.writeUTF(tab[i]);
				
		// Envoi du fichier
		Commun.transfert(
				new FileInputStream(new File("D:\\test1.png")),
				out,
				true);
		
		// Fermeture de la communication
		sock.close();
	} 
}
0
EminoMeneko Messages postés 2435 Date d'inscription jeudi 24 janvier 2008 Statut Membre Dernière intervention 23 mai 2018 318
25 oct. 2011 à 16:44
Ce que je ne comprends pas c'est pourquoi vous souhaitez explicitement faire passer vos données sur plusieurs machines.
Java ou pas un socket permet d'encapsuler les données et ensuite c'est au niveau du réseau que le routage se fait. Pas besoin de s'en soucier.
Est-ce que c'est vraiment le projet que vous vous êtes fixé ou bien vous vous embêtez pour rien ?
Si c'est bien votre souhait alors c'est de la programmation réseau avancée. :) Vous voulez réécrire des routeurs en Java en somme.
0
KX Messages postés 16754 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 020
26 oct. 2011 à 22:30
Si j'ai bien compris, le fichier transféré est un exécutable qui doit être lancé sur les serveurs cibles.
Ce n'est donc pas tout à fait pour remplacer les routeurs ;-)
0
othmane19 Messages postés 96 Date d'inscription jeudi 16 avril 2009 Statut Membre Dernière intervention 27 avril 2013
26 oct. 2011 à 22:09
je te remerci bien pour le code ca ma beaucoup,aidé juste une chose afin que le serveur intermédiaire relaye le fichier recu doit on créer une nouvelle socket avec une nouvelle adresse,et du faite que je teste en local comment je peux lancer plusieur consol avec des adresse ip different
et pour le code je doit juste reprendre le bloc du code client qui permet d'envoyer le fichier et le copier vers les serveur intermediare en changant les adresse a chaque fois(soit en creant une nouvelle socket)?????le probleme c'est l adresse localhost il sera pas toujours valable et il faut des adresse de console serveur differnt

si ta des reponse merci de bien m aider
et merci de votre comprehenssion
0
KX Messages postés 16754 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 020
26 oct. 2011 à 22:38
Pour qu'une machine relaye un fichier, il faut qu'après avoir été serveur, il devienne client.
Effectivement, j'ai mis localhost dans l'exemple, mais l'adresse du serveur à joindre par la suite sera le premier de la liste de l'en-tête (qu'il faut donc enlever pour construire l'en-tête suivant)
Le client sera donc la machine jointe avec une liste vide.
0
othmane19 Messages postés 96 Date d'inscription jeudi 16 avril 2009 Statut Membre Dernière intervention 27 avril 2013
27 oct. 2011 à 11:56
oui j'ai bien compris ca mais tu pense pas qui il faut donner des adresses differentes au serveur intermediare pour que on puisse identifier les serveur du chemin emprunté et du faite que le teste c'est sur une machine local qui seront ses adresse local different ???
merci de votre comprehnssion.
0
KX Messages postés 16754 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 020
27 oct. 2011 à 14:19
Je ne comprends pas la fin de ta phrase : "et du faite que le teste c'est sur une machine local qui seront ses adresse local different ???"

Quant aux adresses différentes à donner au serveur intermédiaire, elles lui sont communiquées dans la liste qu'il reçoit. Si ce que tu veux c'est te "souvenir" par quels serveurs intermédiaires le message vient de passer, tu n'as qu'à rajouter un entier dans l'en-tête qui te servira d'indice. La liste sera donc inchangé tout au long du parcours, seul l'indice sera incrémenté pour identifier le serveur suivant à contacter.
0
othmane19 Messages postés 96 Date d'inscription jeudi 16 avril 2009 Statut Membre Dernière intervention 27 avril 2013
27 oct. 2011 à 17:47
parce que en fait le but c'est que chaque serveur intermediare doit avoir une adresse logique pour l'identifier, ca va aider surtout pour faire les table de routage au niveau de chaque serveur
sourceIP destinatioIP
0
KX Messages postés 16754 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 020
27 oct. 2011 à 19:55
Et bien dans ta liste tu envoies les adresses logique des serveurs, c'est d'ailleurs pour ça que j'avais mis en exemple tab = {"Serveur1", "Serveur2", "Client"};
Quand tu veux envoyer le fichier au prochain serveur tu utilise le code client sauf qu'au lieu d'avoir InetAddress.getLocalHost() comme dans mon code, tu dois avoir InetAddress.getByName(tab[0]);
0

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

Posez votre question
othmane19 Messages postés 96 Date d'inscription jeudi 16 avril 2009 Statut Membre Dernière intervention 27 avril 2013
27 oct. 2011 à 23:26
je pense q'on s'est pas bien compris qand tu met serveur1 comme detination le programme ne se compilera pas du fait q il comprend pas c'est quoi serveur1 car il faut mettre une adresse significatife ou nom de machine et moi j'ai pas une machine qui se nome serveur1
je te rapple que je vx lancer plusieur consol avec des identifiant different
j'espaire que t une idé pour s'y faire
et merci de votre comprehension
0
KX Messages postés 16754 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 020
28 oct. 2011 à 00:20
Je ne mets pas serveur1, mais "serveur1", avec des guillemets, ce sont des String pas des variables (regarde le type de tab). Donc il n'y aura pas de problème à la compilation vu que Java ne regarde pas le contenu des String, seul le type l'intéresse.
Chaque machine a une adresse et un nom (voire plusieurs alias) que tu peux utiliser dans la liste.
Par exemple tu peux passer l'adresse "127.0.0.1", ou bien son nom "localhost", et bien évidemment c'est valable pour les noms et adresses de toutes les machines de ton réseau.
Evidemment si tu veux travailler en local ça va être un peu plus compliqué à tester, vu qu'il te faut un réseau, mais avec une machine virtuelle ça reste faisable.
0
othmane19 Messages postés 96 Date d'inscription jeudi 16 avril 2009 Statut Membre Dernière intervention 27 avril 2013
28 oct. 2011 à 01:25
justement c'est ca mon probléme c'est simuler plusieurs machine en local avec nom different ?????
0
arth Messages postés 9374 Date d'inscription mardi 27 septembre 2005 Statut Contributeur Dernière intervention 16 décembre 2016 1 292
28 oct. 2011 à 02:43
Pas forcément obligé de simuler plusieurs machines, il suffit de changer le port d'écoute.

Soit on a des conditions réelles, soit il faut tout faire pour s'en approcher au MAX.

Ou alors virtualiser des machines linux sur ton PC, mais bon ça nécessite un peu de puissance.
0
othmane19 Messages postés 96 Date d'inscription jeudi 16 avril 2009 Statut Membre Dernière intervention 27 avril 2013
28 oct. 2011 à 13:52
merci de votre réponse
l'idée de changer le port ca peut marcher mais moi je cherche a remplir des table de routage pour spécifier des chemins, donc j'ai besoin d'adresse ip pour identifier les machine
0
KX Messages postés 16754 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 020
28 oct. 2011 à 13:59
Vu que tu n'as qu'une seule machine, tes tables de routage seront très limitées !
Mais dans l'absolu ton code doit pouvoir marcher si la liste des adresses ip sont ["localhost", "localhost", "localhost"] sans même avoir changer de port.
Lorsque le serveur reçoit le fichier (de lui même) il interrompt la communication, il peut donc réutiliser le même port pour relayer le fichier (à lui même du coup)
0
arth Messages postés 9374 Date d'inscription mardi 27 septembre 2005 Statut Contributeur Dernière intervention 16 décembre 2016 1 292
28 oct. 2011 à 14:19
Pas faux aussi :-)
0
othmane19 Messages postés 96 Date d'inscription jeudi 16 avril 2009 Statut Membre Dernière intervention 27 avril 2013
29 oct. 2011 à 00:44
bonjour,
je commence a penser a installer des machiness virtuel pour pouvoir tester, en attendant j'ai essayé de faire le code qui permet de relayer le fichier au niveau de chaque serveur, du coup au niveau du serveur1 aprés avoir recu le fichier et le tableau du chemin il doit crer une nouvelle socket d'envoi du faite q il va se transformer au client j'ai propsé le code qui doit se repter sur chaque serveur intermediare
le probleme c'est java il accepte pas de crer une nouvelle soket d'envoi sachant q'une socket de reception autant que serveur est deja cré. voila le code que j'ai essayé si t une idé comment s'y faire n'hesiter pas a me debloquer
le code c'est une suite de ce que t coder au niveau serveur
donc j'ai gardé le meme principe en creant une nouvelle socket avec une nouvelle adresse t[0] je pense que c'est le code qui je doit mettre sur chaque serveur intermedaire .

et merci de votre comprension

// Affichage de l'en-tête
//bloc qui se repete sur chaque serveur intermediare
for (String s : tab)
System.out.println(s);

if(tab[0]!="client" ||tab[0]!=null) //si la case contient null il passe a la suivante
//creation nouveau socket d'envoi
Socket sock2 = new Socket(tab[0],9001);

tab[0]=null; //facon pour supprimer le premier saut du chemin qui servira rien

ObjectOutputStream out = new ObjectOutputStream(sock.getOutputStream());


//envoi du tableau
out.writeInt(tab.length);
for (int i=0; i<tab.length; i++)
out.writeUTF(tab[i]);

// Envoi du fichier
commun.transfert(new FileInputStream(new File("C:\\M2\\logo.png")),out,true);
0
KX Messages postés 16754 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 020
29 oct. 2011 à 15:51
Tu ne peux pas ouvrir sock et sock2 en même temps sur le même port.
Il faut attendre que sock soit fermée (après le transfert) pour ouvrir sock2.
D'ailleurs ici ton sock2 ne sers à rien, tu peux le supprimer.

Moi j'avais mis le code client et serveur dans deux main, mais il faudrait plutôt en faire des méthodes static, vu que chaque serveur va devoir lancer les deux l'un après l'autre.

Pour t'éviter ta manipulation de "null" dans ton tableau tu peux utiliser une LinkedList et faire des removeFirst.

Voici un code, qui peut t'aider à bien continuer, je ne dis pas qu'il fonctionne correctement, d'ailleurs j'ai moi aussi des problèmes avec le bind mais si au lieu de faire des throws tu gère les Exception avec des try/catch ça devrait mieux passer (idée : si tu lèves BindException, tu fermes la socket, tu attends 1 seconde, et tu réessayes)

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;

import java.net.ServerSocket;
import java.net.Socket;

import java.util.LinkedList;

public class Commun
{
	public static final int port = 9001;
	
	public static void transfert(String role, InputStream in, OutputStream out, boolean closeOnExit) throws IOException
	{
		System.err.println(role+" transfert");
		
		byte buf[] = new byte[1024];
		
		int n;
		while((n=in.read(buf))!=-1)
			out.write(buf,0,n);
		
		if (closeOnExit)
		{
			in.close();
			out.close();
		}
	}
	
	public static void envoi(String role, LinkedList<String> serveurs, File fichier) throws IOException
	{
		System.err.println(role+" envoi");
		// Ouverture de la communication
		Socket sock = new Socket(serveurs.getFirst(),Commun.port);
		ObjectOutputStream out = new ObjectOutputStream(sock.getOutputStream());
	
		// Envoi de l'en-tête
		out.writeInt(serveurs.size());
		for (String srv : serveurs)
			out.writeUTF(srv);
						
		// Envoi du fichier
		Commun.transfert(
			role,
			new FileInputStream(fichier),
			out,
			true);
		
		// Fermeture de la communication
		sock.close();
	}
	
	public static LinkedList<String> recevoir(String role, File fichier) throws IOException 
	{
		System.err.println(role+" recevoir");
					
		// Ouverture d'une communication
		Socket sock = new ServerSocket(Commun.port).accept();
		ObjectInputStream in = new ObjectInputStream(sock.getInputStream());
		
		// Réception de l'en-tête
		int n = in.readInt();
		
		LinkedList<String> serveurs = new LinkedList<String>();
		
		for (int i=0; i<n; i++)
			serveurs.add(in.readUTF());
							
		// Réception du fichier
		Commun.transfert(
				role,
				in,
				new FileOutputStream(fichier),
				true);
		
		// Fermeture de la communication
		sock.close();
				
		return serveurs;
	} 
	
	public static void repeter(String role, LinkedList<String> serveurs, File fichier) throws IOException
	{		
		// Client
		if (serveurs!=null && serveurs.size()>0)
			envoi(role, serveurs,fichier);
		
		// Serveur
		serveurs = recevoir(role, fichier);
		serveurs.removeFirst();
		
		// On recommence
		repeter(role, serveurs, fichier);
	}
	
	public static void main(String...args) throws IOException
	{
		// Serveur
		new Thread() 
		{
			@Override
			public void run()
			{
				try {
					repeter("Thread 1",null,new File("D:\\test2.png"));
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}.start();
				
		final LinkedList<String> serveurs = new LinkedList<String>();
			serveurs.add("localhost");
			serveurs.add("localhost");
			serveurs.add("localhost");
		
		// Client
		new Thread() 
		{
			@Override
			public void run()
			{
				try {
					repeter("Thread 2",serveurs,new File("D:\\test1.png"));
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}.start();
	}
}
0
othmane19 Messages postés 96 Date d'inscription jeudi 16 avril 2009 Statut Membre Dernière intervention 27 avril 2013
30 oct. 2011 à 18:50
ca ma pris un peut de temps de comprendre ton code mais je comprend pas a quoi sert le parametre role
merci pour ta reponse
0
othmane19 Messages postés 96 Date d'inscription jeudi 16 avril 2009 Statut Membre Dernière intervention 27 avril 2013
30 oct. 2011 à 19:11
j'avoue que j'ai un peux du mal a bien assmiler toute les parties du code
l'utilisation des thread c m a un peut gener
le faite de ne pas supposer un liste des serveur au prelable
0
othmane19 Messages postés 96 Date d'inscription jeudi 16 avril 2009 Statut Membre Dernière intervention 27 avril 2013
30 oct. 2011 à 19:20
je te demande juste une petite explication a partir du bloc de la methode main jusqu'a la fin c'est la ou j'ai du mal un peu
merci de votre comprehension
0
KX Messages postés 16754 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 020
30 oct. 2011 à 19:39
Les threads permettent de lancer deux executions en parallèles, ce qui me permet de lancer le serveur dans le Thread1, et le client dans le Thread2.

Le paramètre role ne sert à rien, c'est juste pour débugger. En effet comme les deux threads tournent en même temps sur la même console, on ne sait plus trop qui affiche quoi. Avec le role on peut savoir qui affiche quoi. Par exemple au début, les deux threads sont lancés : Thread1 (serveur) affiche "Thread 1 recevoir", et Thread2 (client) affiche "Thread 2 envoi".

Mais tu peux très bien rajouter deux classes supplémentaires, avec deux main, le premier avec le code de Thread1, l'autre avec le code de Thread2.

class A
{
	public static void main(String...args) throws Exception
	{
		Commun.repeter("A",null,new File("D:\\test2.png"));
	}
}

class B
{
	public static void main(String...args) throws Exception
	{
		LinkedList<String> serveurs = new LinkedList<String>();
			serveurs.add("localhost");
			serveurs.add("localhost");
			serveurs.add("localhost");
			
		Commun.repeter("B",serveurs,new File("D:\\test1.png"));
	}
}

Ce sera peut-être plus simple comme ça ;-)
0
othmane19 Messages postés 96 Date d'inscription jeudi 16 avril 2009 Statut Membre Dernière intervention 27 avril 2013
1 nov. 2011 à 20:35
bon je galére un peu avec ce code pour le faire marcher stp si t une idé sur les bloc q il faut corriger n'hesiter a me le faire passer ca ma bcp m'aider pour econimser le temps car je pense que j'essayé le max mais j arrive pas
sachant que j'ai commencé a reflichir sur la partie routage et j'ai imaginé un petit peu le scenario
0
othmane19 Messages postés 96 Date d'inscription jeudi 16 avril 2009 Statut Membre Dernière intervention 27 avril 2013
4 nov. 2011 à 10:56
bonjour,
j'attende toujours ta reponse
et merci de votre compréhension
0
othmane19 Messages postés 96 Date d'inscription jeudi 16 avril 2009 Statut Membre Dernière intervention 27 avril 2013
6 nov. 2011 à 14:29
s'il te plait j'ai du mal pour tester le code
pourrai je avoir une reponse meme si pour un dernier fois
merci de votre comprehension
0
KX Messages postés 16754 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 020
6 nov. 2011 à 14:40
1) Tu copies-colles la classe Commun dans un fichier Commun.java, tu compiles et tu exécutes.

2) Tu copies-colles les classes A et B dans deux fichiers A.java et B.java, et tu exécutes A, puis B

Tu choisis l'une des deux méthodes au choix, ça fera la même chose (j'avais fait la deuxième uniquement parce que tu ne comprenais pas la première)
Je ne vois vraiment pas ce qu'il y a de compliqué à tester ça...
0
othmane19 Messages postés 96 Date d'inscription jeudi 16 avril 2009 Statut Membre Dernière intervention 27 avril 2013
6 nov. 2011 à 15:16
pour la classe commun j'ai gardé les methode repeter et envoi et recevoir transert
et pour la classe client voila le code:(j pense que le serveur quand il recoit la liste il la relay pas)
public class client
{
public static void main(String[] args) throws IOException
{


// Ouverture de la communication





new Thread()
{
@Override
public void run()
{
final LinkedList<String> serveurs = new LinkedList<String>();
serveurs.add("localhost");
serveurs.add("localhost");
serveurs.add("localhost");
try {
Commun.repeter("Thread 2",serveurs,new File("C:\\M1\\oth.png"));
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}


// Fermeture de la communication

}



et pour la classe serveur
public class serveur
{

public static void main(String[] args) throws IOException
{
// Serveur
new Thread()
{
@Override
public void run()
{
try {
Commun.repeter("Thread 1",null,new File("D:\\t15.png"));
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
0
KX Messages postés 16754 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 020
6 nov. 2011 à 15:24
Comme je l'avait dit au moment où j'ai publié le code, il y a encore des bugs quand on est en local, parce qu'il faudrait temporiser entre le moment où on ferme la socket et le moment où on la réouvre.
Mais si tu testes ça sur plusieurs machines ça devrait aller.

Remarque : si tu as deux main différents, les threads ne servent plus à rien (voir les classes A et B)
0
othmane19 Messages postés 96 Date d'inscription jeudi 16 avril 2009 Statut Membre Dernière intervention 27 avril 2013
6 nov. 2011 à 16:06
si j'ai bien compris
s'il s'agit de plusieur serveur il suffit de refaire ce code sur chaque main du fichier serveur
Commun.repeter("A",null,new File("D:\\test2.png"));
donc (classeB=client) classeA=seveur


reste une chose et vu que le seveur doit transmeetre la liste tu pense pas que ce null( prametre2 de la methode repeter) est anormal
merci de votre comprension
0
KX Messages postés 16754 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 020
6 nov. 2011 à 16:17
C'est moi qui ait décidé dans la méthode repeter que le paramètre "serveurs" pouvait prendre la valeur null. Si on est client, on a une liste à envoyer, donc une liste avec plusieurs serveurs cibles (l'un après l'autre) mais lorsqu'on est serveur, on attend une liste, mais donc au départ on ne connait pas sa valeur, c'est pour ça qu'on met null.

null -> serveur attend une llste
non-null -> client envoie la liste
0
othmane19 Messages postés 96 Date d'inscription jeudi 16 avril 2009 Statut Membre Dernière intervention 27 avril 2013
6 nov. 2011 à 18:00
ok j'ai compris
confirme moi ca s'il te plait:
s'il s'agit de plusieur serveur il suffit de refaire ce code sur chaque main du fichier serveur
Commun.repeter("A",null,new File("D:\\test2.png"));

donc (classeB=client) classeA=seveur
et la classe comun c est c'est ca:

public class Commun
{
public static final int port = 9001;

public static void transfert(String role, InputStream in, OutputStream out, boolean closeOnExit) throws IOException
{
System.err.println(role+" transfert");

byte buf[] = new byte[1024];

int n;
while((n=in.read(buf))!=-1)
out.write(buf,0,n);

if (closeOnExit)
{
in.close();
out.close();
}
}

public static void envoi(String role, LinkedList<String> serveurs, File fichier) throws IOException
{
System.err.println(role+" envoi");
// Ouverture de la communication
Socket sock = new Socket(serveurs.getFirst(),Commun.port);
ObjectOutputStream out = new ObjectOutputStream(sock.getOutputStream());

// Envoi de l'en-tête
out.writeInt(serveurs.size());
for (String srv : serveurs)
out.writeUTF(srv);

// Envoi du fichier
Commun.transfert(
role,
new FileInputStream(fichier),
out,
true);

// Fermeture de la communication
sock.close();
}

public static LinkedList<String> recevoir(String role, File fichier) throws IOException
{
System.err.println(role+" recevoir");

// Ouverture d'une communication
Socket sock = new ServerSocket(Commun.port).accept();
ObjectInputStream in = new ObjectInputStream(sock.getInputStream());

// Réception de l'en-tête
int n = in.readInt();

LinkedList<String> serveurs = new LinkedList<String>();

for (int i=0; i<n; i++)
serveurs.add(in.readUTF());

// Réception du fichier
Commun.transfert(
role,
in,
new FileOutputStream(fichier),
true);

// Fermeture de la communication
sock.close();

return serveurs;
}

public static void repeter(String role, LinkedList<String> serveurs, File fichier) throws IOException
{
// Client
if (serveurs!=null && serveurs.size()>0)
envoi(role, serveurs,fichier);

// Serveur
serveurs = recevoir(role, fichier);
serveurs.removeFirst();

// On recommence
repeter(role, serveurs, fichier);
}

}


donc si je teste sur une machine virtuel:
client=classeB
et sur chaque serveur je met le code de la classe A
reste juste a changer la liste au fonction de nombre et les adresse des serveur intermedaire.
j attend ta confirmation sur ca s'il te plait
et merci de votre comprhension.
0
KX Messages postés 16754 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 020
6 nov. 2011 à 18:34
C'est un peu plus compliqué que ça, car le "serveur" devient à son tour "client" lorsqu'il a reçu des données. Donc on ne peut pas dire client=classeB ou serveur=classeA, c'est pour ça que j'avais préféré tout faire dans la classe Commun car en fait ils ont tous le même comportement.
La seule différence entre A et B, c'est qu'au lancement A envoie un fichier. Mais on peut très bien imaginer qu'on démarre tout le monde avec une classe B (ils attendent tous des fichiers) et de temps en temps on envoie un fichier (avec la classe A ou une autre).
0
othmane19 Messages postés 96 Date d'inscription jeudi 16 avril 2009 Statut Membre Dernière intervention 27 avril 2013
6 nov. 2011 à 19:14
oui je pense que j'ai compris la problématique
dnc pour pouvoir tester le transfert entre plusieur machine tu propose quoi comme code sur le client et le serveur si on va pas reprendre le code de la classe A et B
merci de votre comprehension
0
KX Messages postés 16754 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 020
6 nov. 2011 à 19:21
Tu dois lancer le programme role=B sur toutes tes machines. Et une fois que c'est fait envoyer un fichier avec le programme role=A, éventuellement modifié pour s'arrêter une fois le fichier envoyé, et attendre de voir ce que font les machines B avec. À la fin il est possible que tu ais une machine role=C, qui reçoive le fichier, mais là encore ce n'est qu'un cas particulier de B, où la liste arrive vide.
0
othmane19 Messages postés 96 Date d'inscription jeudi 16 avril 2009 Statut Membre Dernière intervention 27 avril 2013
8 nov. 2011 à 00:59
je pense que c'est pas claire s'il te plait pourrai tu me donner le code par ce que la ca commence a me prendre la tete
code client =?
code serveur=?
code commun =?
s'il te plait.
et merci de votre comprehension.
0
othmane19 Messages postés 96 Date d'inscription jeudi 16 avril 2009 Statut Membre Dernière intervention 27 avril 2013
8 nov. 2011 à 01:00
parce que la j'ai installé vmware avec 2 macine et je compte faire l 3 machine
0