Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
/*main methode*/
Server server = new Server(tcpPort);
new Thread(server).start();
try {
Thread.sleep(1000*60); /* 60 Sekunden*/
} catch (InterruptedException e) {
e.printStackTrace();
}
server.stop;
...
Dies war mein provisorischer Server-Start-Code. Der Server wird gestartet und läuft dann für 60 Sekunden.
Jetzt möchte ich aber, dass der Server nicht für 60 Sekunden läuft, sondern solange läuft, bis die Eingabe der Enter-Taste erfolgt (also: Es kommt ein leeres readLine oder so daher).
Habe das ausprobiert, will aber nicht so recht. was mache ich währenddessen mit dem Thread? Ich kann ja nicht jedesmal, wenn keine Eingabe kommt, nochmal für 1 Sekunde oder so sleepen...
solange keine Eingabe kommt musst du gar nichts machen, lege den Thread etwas gloabler ab und niemand muss mit einer Schleife warten, jedenfalls nicht deswegen,
irgendjemand muss aber schon auf die Eingabe aufpassen,
und genau wenn dort eine Enter-Taste festgestellt wird, muss (evtl. neben anderen Aufgaben) der Thread gestoppt werden
> Was heißt, globaler ablegen?
wenn nicht diese Methode irgendwie wartet und am Ende stopt, sondern eine andere Methode, gar andere Klasse,
dann den Thread oder den Server in ein Instanzattribut ablegen, statisches Attribut, irgendwohin übergeben
System.in.read();
dürfte blockieren, wer immer auf die Tastatur achtet, eben wartet,
einen neuer Thread bzw. die Tätigkeit eines Server-Objektes sollte das nicht beeinträchtigen,
da fällt mir nichts zu ein, evtl. mit mehr Info/ mehr Code
Ja, dürfte blockieren, aber dann werden keine Clients mehr akzeptiert. Mehr Code gibt es dazu nicht wirklich. Der Server arbeitet mit ExecutorService und startet dann eben seine Worker...aber anscheinend nur, wenn der Main Thread nicht blockiert, sondern auf sleep ist.
Ich will den Main thread ja nicht einschläfern, sondern einfach auf die Eingabe warten. Der Server Thread sollte ja trotzdem weiterlaufen und alles erledigen (was er WUNDERBAR macht, wenn ich sleep in der main-methode mache, aber nicht mehr, wenn ich read mache!)
Hier fehlen einige Klassen (lässt sich so nicht kompilieren), und der Worker ist unübersichtlich und macht sicher vieles schlecht (Stringoperationen), aber bitte auf die Frage konzentrieren. Alles Wesentliche dafür sollte enthalten sein.
Ich versuchs jetzt somit einfach, entschuldige nochmal SlaterB, habe gedacht du hättest die Fragestellung missverstanden, was nicht der Fall war.
Oops: Sollte es wichtig sein: Der Notificationsender sendet nur UDP packets, habe ihn auch auskommentiert er sollte das Ganze nicht beeinflussen.
zu entschuldigen ist immer nichts, Aktion und Reaktion wie es in manchem Film heißt
ich sehe keinerlei Probleme im Code, außer dass ich jede Menge löschen musste was nicht geht und überhaupt nur ausnahmsweise die fremde Quelle nehme,
wie du selbst sagst hat der Notificationsender nichts damit zu tun
Java:
public class Test2
{
public static void main(String[] args)
{
MainServer.main(null);
}
}
class MainServer
{
private static int tcpPort = 9999;
public static void main(String[] args)
{
Runnable r = new Runnable()
{
public void run()
{
try
{
while (true)
{
Thread.sleep(2000);
Socket s = new Socket("localhost", tcpPort);
s.getOutputStream().write(68);
s.close();
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
};
new Thread(r).start();
Server server = new Server(tcpPort);
new Thread(server).start();
// NotificationSender notificationSender = new NotificationSender();
// new Thread(notificationSender).start();
//
// try
// {
// Thread.sleep(8 * 1000);
// }
// catch (InterruptedException e)
// {
// e.printStackTrace();
// }
try
{
System.in.read();
}
catch (IOException e)
{
e.printStackTrace();
}
System.out.println("Stopping Server");
server.stop();
// notificationSender.halt();
}
}
class Server
implements Runnable
{
private int tcpPort;
private ServerSocket serverSocket = null;
private boolean isStopped = false;
private Thread runningThread = null;
private ExecutorService threadPool = Executors.newFixedThreadPool(6);
public Server(int tcpPort)
{
this.tcpPort = tcpPort;
}
public void run()
{
synchronized (this)
{
this.runningThread = Thread.currentThread();
}
openServerSocket();
while (!isStopped())
{
Socket tcpSocket = null;
try
{
tcpSocket = this.serverSocket.accept();
System.out.println("accept: " + tcpSocket.getPort());
}
catch (IOException e)
{
if (isStopped())
{
System.out.println("Server Stopped.");
return;
}
throw new RuntimeException("Error accepting client connection", e);
}
this.threadPool.execute(new Worker(tcpSocket));
}
this.threadPool.shutdown();
System.out.println("Server Stopped.");
}
private boolean isStopped()
{
return this.isStopped;
}
public void stop()
{
try
{
isStopped = true;
this.serverSocket.close();
}
catch (IOException e)
{
throw new RuntimeException("Error closing server", e);
}
threadPool.shutdown(); /* right here? */
this.isStopped = true;
}
private void openServerSocket()
{
try
{
this.serverSocket = new ServerSocket(this.tcpPort);
}
catch (IOException e)
{
throw new RuntimeException("Cannot open port number " + this.tcpPort, e);
}
}
}
class Worker
implements Runnable
{
private int udpPort = 4000;
private InetAddress inetAddress = null;
private Socket tcpSocket = null;
private DatagramSocket highestSocket = null;
private DatagramPacket udpPacket = null;
// private LoginService loginService = LoginService.getInstance();
private BufferedReader input = null;
private PrintWriter output = null;
private Boolean shutdown = false;
public Worker(Socket tcpSocket)
{
this.tcpSocket = tcpSocket;
}
public void run()
{
String inputMessage = "";
inetAddress = tcpSocket.getInetAddress();
try
{
input = new BufferedReader(new InputStreamReader(tcpSocket.getInputStream()));
output = new PrintWriter(tcpSocket.getOutputStream(), true);
while (!shutdown)
{
inputMessage = input.readLine();
if (inputMessage != null)
{
processInput(inputMessage);
}
}
System.out.println("Worker shutting down");
input.close();
output.close();
}
catch (IOException e)
{
// report exception somewhere.
System.out.println("Error reading/sending IO");
e.printStackTrace();
}
}
private void processInput(String input)
{
System.out.println("input: " + input);
}
public void stop()
{
try
{
output.println("Server has ended. You have been logged out.");
shutdown = true;
tcpSocket.close();
}
catch (IOException e)
{
System.out.println("Closing worker");
}
}
}
ist das was man unter einem vollständigen Testprogramm versteht, kopieren, mit evtl. gleichnamigen eigenen Klassen aufpassen,
Imports automatisch ergänzen lassen, laufen lassen, fertig
Server wird gestartet, alle 2 sec kommt ein Client, keine Spur einer Fehlermöglichkeit,
welche Art Fehlverhalten stellst du dir denn vor?
was ich mir im letzten Posting noch gespart habe war der allgemeine Hinweis,
dass vielleicht andere Stellen auch auf System.in lesen, dann mag ein zusätzliches System.in.read() Auswirkungen haben,
wobei man auch dann noch schwer überlegen muss, etwa dass woanders ein Enter nicht ankommt und es dort dann nicht weitergeht
das wäre dann ja noch ein Java-Fehler,
kannst du mein Programm auf irgendeinem Rechner unter irgendeiner Konfiguration tatsächlich zu Problemen führen?
wenn ja welche Probleme genau, und welche Konstellation wäre das?