Créer un reseau en java
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.
26 réponses
Plusieurs intervenants discutent de la création d'un réseau virtuel en Java utilisant des machines intermédiaires qui relaient un fichier entre une source et une destination, par sockets et IP. Des machines intermédiaires seraient des serveurs: le fichier est adressé au serveur, qui peut exécuter le programme et relayer ensuite vers le client final ou vers un autre serveur intermédiaire. Des propositions évoquent soit une liste d'adresses des nœuds à traverser, soit un en-tête indiquant le prochain relais ou un routage dynamique basé sur des métriques statiques entre machines. Pour une approche pratique, des exemples montrent qu'un chemin simple impliquant une chaîne de serveurs locaux peut constituer une première étape, même sans routeur dédié, avant d'aborder des scénarios plus complexes.
-
il sera top tard bon c 'est mort
en tt cas merci -
ModérateurJ'avoue que ça fais plusieurs fois que je vois tes messages et que je n'y réponds pas, mais c'est parce que ton problème est assez compliqué et que je n'ai pas trop le temps en ce moment pour m'y consacrer d'avantage. ça ira mieux dans une semaine ;-)
Donc si tu as le temps d'attendre jusque là je regarderai tout ça attentivement et te dirai ce que j'en pense. Mais pour l'instant je n'ai guère plus de temps à consacrer au forum que quelques petites aides hyper-faciles qui me prennent 5 minutes maxi, ce qui n'est pas ton cas. J'espère que tu comprendras :) -
bonjour
je vous est mis le sujet afin que vous puissiez comprendre le sujet il s'agit d'une application qui fait le transfert d'un fichier en utilisant un socket java a travers un réseau de recouvrement
s'il vous plait si vous avez une idée comment s'y faire n'hésiter pas
merci de votre aide d'avance
Mise en place du réseau de recouvrement
Les équipements cibles doivent disposer d'une application permettant la réception des contenus. Ces applications
sont interconnectées au moyen d'éléments d'interconnexion (dénommés ci-après routeurs de recouvrement). Par
le maillage de leur interconnexion, les routeurs de recouvrements assurent le routage et le transfert des contenus
vers les équipements cibles. Ces fonctionnalités supposent que les routeurs de recouvrement disposent d'une
application dédiée.
Cette première étape consiste à mettre en place l'interconnexion logique entre les équipements cibles. Dans cette
version, on se limitera à une interconnexion statique prévue à l'avance.
A chaque application sera associée une adresse logique sur le réseau de recouvrement. Le choix des critères
d'attribution de ces adresses est laissé à votre convenance. -
j attend ton avis s 'il te plait
-
j'ai reussi en se basant juste sur les numero de port
et voila le code j'ai savoir q est ce que t on pense
j ai simuler un envoi de client vers serveur en passant par A et B et C
s il te plait dit q est ce que tu en pense
et merci de votre aide
pour la classe commun j ai gardé la même:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
client
public class cl
{
public static void main(String[] args) throws IOException
{
Socket sock = new Socket(InetAddress.getLocalHost(),9001);
commun.transfert(new FileInputStream("C:\\M1\\oth.png"),sock.getOutputStream(),true);
sock.close();
}
}
A
public class A
{
public static void main(String[] args) throws IOException
{
Socket sock = new ServerSocket(9001).accept();
//recevoir
commun.transfert(
sock.getInputStream(),
new FileOutputStream("C:\\M2\\f1.png"),
true);
//envoyer//
Socket sock2 = new Socket(InetAddress.getLocalHost(),9002);
commun.transfert(new FileInputStream("C:\\M2\\f1.png"),sock2.getOutputStream(),true);
//envoyer//
sock.close();
}
}
B
public class B
{
public static void main(String[] args) throws IOException
{
Socket sock2 = new ServerSocket(9002).accept();
//recevoir
commun.transfert(
sock2.getInputStream(),
new FileOutputStream("C:\\M3\\finale.png"),
true);
int a=0;
int port;
//envoyer a 9004//
if(a==1)
{
port=9004;
}
else
port=9003;
Socket sock3 = new Socket(InetAddress.getLocalHost(),port);
commun.transfert(new FileInputStream("C:\\M3\\finale.png"),sock3.getOutputStream(),true);
sock2.close();
}
}
C
public class C
{
public static void main(String[] args) throws IOException
{
Socket sock3 = new ServerSocket(9003).accept();
//recevoir
commun.transfert(
sock3.getInputStream(),
new FileOutputStream("C:\\M4\\finale.png"),
true);
//envoyer//
Socket sock4 = new Socket(InetAddress.getLocalHost(),9004);
commun.transfert(new FileInputStream("C:\\M4\\finale.png"),sock4.getOutputStream(),true);
sock3.close();
}
}
public class srv
{
public static void main(String[] args) throws IOException
{
Socket sock4 = new ServerSocket(9004).accept();
commun.transfert(
sock4.getInputStream(),
new FileOutputStream("C:\\M5\\finale.png"),
true);
sock4.close();
}
} -
je pense que on aura pas besoin des machine virtuel car la connexion est logique donc on vas pas se soucier des carte réseau et port et tous ca..
qu'est ce que t en pense ?? -
parce que la j'ai installé vmware avec 2 macine et je compte faire l 3 machine
-
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.-
ModérateurC'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). -
-
ModérateurTu 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.
-
-
-
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-
ModérateurC'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
-
-
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();-
ModérateurComme 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)
-
-
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-
Modérateur1) 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...
-
-
bonjour,
j'attende toujours ta reponse
et merci de votre compréhension -
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 -
ModérateurLes 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 ;-) -
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 -
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 -
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 -
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);-
ModérateurTu 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(); } }
-
-
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-
ModérateurVu 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) -
-
-
ContributeurPas 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.
- 1
- 2