Java: Multithreading & Socket UDP Programmation
Je suis nouveau sur le multithreading & socket de programmation en Java. Je voudrais savoir quelle est la meilleure façon de mettre 2 fils - un pour recevoir un support et une pour l'envoi d'un socket. Si ce que je suis en train de faire semble absurde, s'il vous plaît laissez-moi savoir pourquoi! Le code est largement inspiré de Soleil des tutoriels en ligne.Je veux utiliser la Multidiffusion sockets afin que je puisse travailler avec un groupe de multidiffusion.
class Server extends Thread
{
static protected MulticastSocket socket = null;
protected BufferedReader in = null;
public InetAddress group;
private static class Receive implements Runnable
{
public void run()
{
try
{
byte[] buf = new byte[256];
DatagramPacket pkt = new DatagramPacket(buf,buf.length);
socket.receive(pkt);
String received = new String(pkt.getData(),0,pkt.getLength());
System.out.println("From server@" + received);
Thread.sleep(1000);
}
catch (IOException e)
{
System.out.println("Error:"+e);
}
catch (InterruptedException e)
{
System.out.println("Error:"+e);
}
}
}
public Server() throws IOException
{
super("server");
socket = new MulticastSocket(4446);
group = InetAddress.getByName("239.231.12.3");
socket.joinGroup(group);
}
public void run()
{
while(1>0)
{
try
{
byte[] buf = new byte[256];
DatagramPacket pkt = new DatagramPacket(buf,buf.length);
//String msg = reader.readLine();
String pid = ManagementFactory.getRuntimeMXBean().getName();
buf = pid.getBytes();
pkt = new DatagramPacket(buf,buf.length,group,4446);
socket.send(pkt);
Thread t = new Thread(new Receive());
t.start();
while(t.isAlive())
{
t.join(1000);
}
sleep(1);
}
catch (IOException e)
{
System.out.println("Error:"+e);
}
catch (InterruptedException e)
{
System.out.println("Error:"+e);
}
}
//socket.close();
}
public static void main(String[] args) throws IOException
{
new Server().start();
//System.out.println("Hello");
}
}
Quel est votre objectif final?
J'ai corrigé votre mise en forme, mais vous devez modifier les noms de classe... leur faire commencer avec une lettre majuscule. C'est pénible à lire votre code lors de votre classe les noms commencent par les lettres minuscules.
Mon objectif final est de mettre en œuvre certaines des protocoles dans un système distribué @Lirik: je Suis désolé pour les noms de classe! J'ai fixé maintenant.
Bon à entendre une réponse qui utilise ExecuterService lorsque vous traitez avec les sockets udp
J'ai corrigé votre mise en forme, mais vous devez modifier les noms de classe... leur faire commencer avec une lettre majuscule. C'est pénible à lire votre code lors de votre classe les noms commencent par les lettres minuscules.
Mon objectif final est de mettre en œuvre certaines des protocoles dans un système distribué @Lirik: je Suis désolé pour les noms de classe! J'ai fixé maintenant.
Bon à entendre une réponse qui utilise ExecuterService lorsque vous traitez avec les sockets udp
OriginalL'auteur Ravi | 2010-04-21
Vous devez vous connecter pour publier un commentaire.
Première chose est d'abord: vos classes doit commencer avec une lettre majuscule par la Conventions De Nommage Java:
Deuxième:
Essayez de diviser le code en sections cohérentes et de les organiser autour de quelques caractéristique commune qui vous avez affaire... peut-être autour de la fonctionnalité ou le modèle de programmation.
L' (de base) pour le modèle de serveur, c'est que le seulement chose qu'il fait est de recevoir des connexions socket... le serveur s'appuie sur un gestionnaire pour gérer les connexions et c'est tout. Si vous essayez de construire ce modèle, il ressemblerait à quelque chose comme ceci:
Troisième: je vous recommande de regarder quelques exemples existants.
http://www.ase.md/~aursu/ClientServerThreads.html
http://www.developer.com/java/ent/article.php/3645111/Java-5s-BlockingQueue.htm (merci à John)
http://gee.cs.oswego.edu/dl/cpj/index.html
(ne trouvez toujours pas l'exemple précis, mais il est là quelque part... si vous vous sentez courageux regarder par-dessus son allcode.java fichier).http://www.javaconcurrencyinpractice.com/listings.html
http://java.sun.com/docs/books/tutorial/essential/concurrency/
Mis à jour par commentaires:
OK Ravi, il y a quelques grand des problèmes avec votre code et mineur problèmes avec elle:
Je suppose que le
Receive
classe est votre client..., vous devez tirer que comme un programme distinct (avec sa propre classe principale) et exécuter votre serveur et plusieurs clients en même temps. Lançant un nouveau "thread client" de votre serveur pour chaque nouveau paquet UDP que vous envoyez est une fâcheuse idée (grand question).Lorsque vous effectuez votre application cliente, vous devez faire tourner la réception de code dans sa propre
while
boucle (mineur de l'émission), par exemple:Vous ne devriez juste besoin d'un thread par client et un thread par serveur (vous, techniquement, ne sont pas même d'un autre thread là depuis principale a son propre thread), de sorte que vous pouvez ne pas trouver le
ExecutorService
que utile.Sinon, votre approche est correcte... mais je encore vous recommandons de consulter quelques exemples.
Ah, oui... merci John, c'est ce que je cherchais.
+1 Bonne réponse !!!!!
la méthode start() sur le serveur de classe dans les Ravi exemple fait partie de la classe Thread, ce qui la classe serveur s'étend. Autre que cela, c'est une excellente réponse.
merci! 🙂 Mise à jour de ma réponse.
OriginalL'auteur
Vouloir créer des threads dans une application n'est pas absurde! Vous n'aurez pas besoin d'exactement 2 threads, mais je pense que vous parlez de 2 classes qui implémentent l'interface Runnable.
Le filetage API a eu mieux depuis Java 1.5 et vous n'avez pas besoin de jouer avec java.lang.Fil plus. Vous pouvez simplement créer un java.util.de façon concomitante.Exécuteur testamentaire et soumettre Praticable instances.
Le livre Java de la Simultanéité dans la Pratique utilise ce problème exact - la création d'un raccord fileté g de serveur et de randonnées à travers plusieurs itérations du code de montrer la meilleure façon de le faire. Découvrez la échantillon gratuit de chapitre, ce qui est excellent. Je ne vais pas copier/coller le code ici, mais regardons de plus au moment de l'inscription 6.8.
Attention!!! Tandis qu'il est toujours parfaitement d'accord pour effectuer une opération de blocage dans une engendré thread (qui sera alors tout simplement bloquer pour un temps), il peut être mortelle pour le faire que dans un
Runnable
instance passée àjava.util.concurrent.Executor
. Pourquoi? Parce que l'Exécuteur ne garantit pas pour exécuter le code sur un autre thread. Il peut ainsi exécuter le code sur le thread appelant. À partir de la documentation: "Cependant, l'Exécuteur testamentaire de l'interface n'est pas strictement besoin que l'exécution asynchrone.". Donc, vous pouvez ainsi bloquer votre thread principal de cette manière et vous pouvez facilement morts de verrouillage de l'ensemble du programme.Bon appel que les questions de mise en œuvre. Un exemple de synchrone impl. serait Printemps de SyncTaskExecutor
OriginalL'auteur Drew
C'est une bonne chose de l'Éclipse de l'histoire des œuvres, même pour un jour de retour 🙂 Merci, je suis en mesure de donner à la fois Ravi un exemple de travail et de Lirik sa réponse en fuite.
Laissez-moi d'abord commencer par disant que je n'ai aucune idée de ce qui est à l'origine de cette fuite, mais si je le laisse suffisamment longtemps, il va échouer sur un OutOfMemoryError.
Deuxième, j'ai laissé le code de travail en commentaire pour Ravi pour un exemple de base de mon serveur UDP. Le délai d'attente est là pour tester combien de temps mon pare-feu de tuer les récepteurs fin (30 secondes). Juste enlever quoi que ce soit à la piscine, et vous êtes bon pour aller.
Donc, ici, c'est un travail mais une fuite de la version de mon exemple filetée UDP serveur.
btw. @Lirik, j'ai été témoin de ce comportement tout d'abord dans Eclipse, après quoi je l'ai testé à partir de la ligne de commande. Et encore, je n'ai PAS la moindre idée de ce qui en est la cause 😉 désolé...
OriginalL'auteur djBo
2 fils est très bien. Un lecteur d'un autre écrivain. Rappelez-vous que avec UDP, vous ne devez pas reproduire nouveau gestionnaire de threads (à moins que ce que vous faites prend beaucoup de temps), je vous recommande de jeter les messages dans une File d'attente de traitement. De même pour l'envoyer, un send thread qui bloque sur une File d'attente entrante UDP pour envoyer.
OriginalL'auteur Jé Queue