Java: Multithreading & UDP-Socket-Programmierung
Ich bin neu auf multithreading & socket-Programmierung in Java. Ich würde gerne wissen, was ist die beste Art der Umsetzung 2 threads - einen für den Empfang eine Steckdose und einen für das senden einer Steckdose. Wenn das, was ich versuche zu tun, klingt absurd, pls lassen Sie mich wissen, warum! Der code ist weitgehend inspiriert von Sonne tutorials online.Ich möchte mit Multicast-sockets, so dass ich arbeiten kann mit einer multicast-Gruppe.
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");
}
}
Was ist dein Endziel?
Ich fixierte Ihre Formatierung, aber man sollte Bearbeiten Sie die Klasse Namen... machen Sie beginnen mit einem Großbuchstaben. Es ist schmerzhaft zu Lesen, Ihre Codes, wenn Sie Ihre Klassen-Namen beginnen mit Kleinbuchstaben.
Mein Ziel ist, die Umsetzung bestimmter Protokolle in einem verteilten system @Lirik: tut mir Leid wegen dem Klasse Namen! Ich fixierte Sie jetzt.
Gut zu beherzigen, eine Antwort, die verwendet ExecuterService beim Umgang mit udp-sockets
Ich fixierte Ihre Formatierung, aber man sollte Bearbeiten Sie die Klasse Namen... machen Sie beginnen mit einem Großbuchstaben. Es ist schmerzhaft zu Lesen, Ihre Codes, wenn Sie Ihre Klassen-Namen beginnen mit Kleinbuchstaben.
Mein Ziel ist, die Umsetzung bestimmter Protokolle in einem verteilten system @Lirik: tut mir Leid wegen dem Klasse Namen! Ich fixierte Sie jetzt.
Gut zu beherzigen, eine Antwort, die verwendet ExecuterService beim Umgang mit udp-sockets
InformationsquelleAutor Ravi | 2010-04-21
Du musst angemeldet sein, um einen Kommentar abzugeben.
Erste, was ist erste: Ihre Klassen beginnen mit einem Großbuchstaben pro die Java-Namenskonventionen:
Zweite:
Versuchen, brechen Sie den code in kohärente Abschnitte, und ordnen Sie um einige gemeinsame Merkmal, dass Sie zu tun haben... vielleicht um die Funktionalität oder das Modell, das Sie Programmieren.
Der (Basis -) Modell für den server ist, dass die nur was es tut, ist, erhalten die socket-verbindungen... der server setzt auf einen handler zur Verarbeitung dieser verbindungen und das ist es. Wenn Sie versuchen, zu bauen, das Modell würde es wie folgt Aussehen:
Dritte: ich würde empfehlen, dass Sie einen Blick auf einige vorhandene Beispiele.
http://www.ase.md/~aursu/ClientServerThreads.html
http://www.developer.com/java/ent/article.php/3645111/Java-5s-BlockingQueue.htm (Dank an John)
http://gee.cs.oswego.edu/dl/cpj/index.html
(immer noch nicht finden können, die genaue Beispiel, aber es ist da, irgendwo... wenn Sie mutig und sah über seine allcode.java - Datei).http://www.javaconcurrencyinpractice.com/listings.html
http://java.sun.com/docs/books/tutorial/essential/concurrency/
Pro aktualisiert Kommentare:
OK, Ravi, gibt es einige großen Probleme mit Ihrem code und einige minor Probleme mit ihm:
Ich gehe davon aus, dass die
Receive
Klasse ist dein client... Sie ziehen sollte, als ein separates Programm (mit seinen eigenen main-Klasse) und Ihre server und mehreren clients zur gleichen Zeit. Erzeugt einen neuen "client-thread", der auf Ihrem server für jeden neuen UDP-Paket, das Sie senden, ist eine verstörende Idee (großen Problem).Werden, wenn Sie Ihre client-Anwendung, Sie sollten es machen, führen Sie den empfangen code in seinem eigenen
while
loop (minor - Ausgabe), z.B.:Sollten Sie nur brauchen nur ein thread pro client und ein thread pro server (technisch noch nicht einmal einen separaten thread gibt, da main hat seinen eigenen thread), so könnten Sie nicht finden, die
ExecutorService
sehr nützlich ist.Sonst dein Ansatz ist richtig... aber ich würde noch empfehlen, dass Sie überprüfen einige Beispiele.
Ah, ja... danke, John, das ist das, was ich suchte.
+1 Gute Antwort !!!!!
die start () - Methode der server-Klasse in Ravi ' s Beispiel ist Teil von der Thread-Klasse die server-Klasse erweitert. Other than, die dies ist eine großartige Antwort.
danke! 🙂 Aktualisiert meine Antwort.
InformationsquelleAutor
Wollen, threads zu erstellen in einer Anwendung ist nicht absurd! Sie nicht brauchen, genau 2 threads, aber ich denke, Sie sprechen über die 2-Klassen-implementieren der Runnable-Schnittstelle.
Threading API ist besser geworden seit Java 1.5 und Sie nicht brauchen, um Durcheinander mit java.lang.Thread nicht mehr. Sie können einfach erstellen Sie eine java.util.gleichzeitige.Testamentsvollstrecker und senden Runnable-Instanzen.
Buch Java Concurrency in Practice verwendet, die genau das problem - die Schaffung eines threaded-socket-server - und Spaziergänge durch mehrere Iterationen der code zum anzeigen der beste Weg, es zu tun. Schauen Sie sich die Kostenlose Probekapitel, das ist toll. Ich will nicht copy/paste den code hier, aber sehen Sie speziell in listing 6.8.
Vorsicht!!! Zwar ist es immer vollkommen in Ordnung, führen Sie eine blockierende operation in einen gestarteten thread (wird dann einfach block für eine Weile), es kann tödlich sein, in einer
Runnable
Instanz übergebenjava.util.concurrent.Executor
. Warum? Weil die Executor garantiert nicht, um den code auszuführen, der in einem anderen thread. Es kann auch der code an den aufrufenden thread. Aus der Dokumentation: "Doch, das Executor-interface nicht zwingend erforderlich, dass die Ausführung asynchron.". So können Sie auch blockieren Ihre Haupt-thread, der Weise, und Sie können einfach tot sperren, das ganze Programm.Guter Ruf hin, dass die Umsetzung ankommt. Ein Beispiel für eine synchrone impl. Spring SyncTaskExecutor
InformationsquelleAutor Drew
Es ist eine gute Sache, die Eclipse Geschichte funktioniert auch für einen Tag zurück 🙂 vielen Dank, dass ich in der Lage bin zu geben, sowohl Ravi als ein Beispiel und Lirik seine Antwort auf undichte stellen.
Lassen Sie mich ersten start indem Sie behaupten, dass ich keine Ahnung habe, was die Ursache für das Leck sein, aber wenn ich es lang genug ist, wird es nicht auf eine OutOfMemoryError.
Zweite, verließ ich den funktionierenden code auskommentiert Ravi für eine funktionierende basic-Beispiel von meinem UDP server. Das timeout war es, zu testen, wie lange meine firewall töten würde den Receiver Ende (30 Sekunden). Entfernen Sie einfach alles, was mit dem pool, und du bist gut zu gehen.
So, hier ist, ein arbeiten, aber die undichte version von meinem Beispiel Gewinde-UDP-server.
btw. @Lirik, erlebte ich dieses Verhalten zuerst in Eclipse, nach dem ich es getestet von der Befehlszeile aus. Und nochmal, ich habe KEINE Ahnung, was die Ursache dafür ist 😉 sorry...
InformationsquelleAutor djBo
2 threads in Ordnung ist. Ein Leser einen anderen Schriftsteller. Denken Sie daran, dass mit UDP sollte man nicht spawnen neue handler-threads (es sei denn, was Sie tun, dauert eine lange Zeit), ich empfehle werfen die eingehenden Nachrichten in einer Verarbeitungs-Warteschlange. Das gleiche für die senden, haben einen schicken thread, dass die Blöcke auf eine Warteschlange für eingehende UDP senden.
InformationsquelleAutor Jé Queue