Ich schreibe gerade an einem Server (in java) der mit Clients (in C++) kommuniziert. Als Kommunikationsweg wurde das http-Protokoll festgelegt.
Der Server horcht in einer while Schleife auf Anfragen aus dem Netz. Wenn eine Anfrage ankommt, wird in dieser while-Schleife in einem neuen Thread eine Bearbeitungsklasse gestartet. In der Bearbeitungsklasse lese ich die Daten verarbeite sie zu einem Ergebnis (hier XML) und will diese zusammen mit einem http-Header an den Client zurückschicken.
Die Daten kommen aber nur dann zuverlässig beim Client an, wenn ich nach dem out.write();out.flush(); eine recht lange Zeit warte. Ich habe deshalb eine sleep-Funktion an dieser Stelle eingebaut.
Wenn ich diese Zeit zu kurz wähle, kommen beim Client nur Bruchstücke zufälliger Länge der zu übertragenden Daten an.
Ich kenne ein solches Problem aus einer reinen C++ Client-Server –Anwendung. Dort hatten wir allerdings kein http-Protokoll verwendet. Wir hatten damals vereinbart, dass der Empfänger immer ein Quittungsbyte an den Sender zurückschickt, wenn er die Daten vollständig erhalten hatte; der Sender musste dann solange warten.
Aber wie kann man das mit dem http_Protokoll machen?
Die sleep-Funktion ist ja nur eine dumme Krücke, die bestimmt nicht unter allen Voraussetzungen rausreicht….
Eine andere Lösung ist, das Socket nicht zu schliessen. Das habe ich auch ausprobiert. Aber was passiert, wenn der Server in den Bearbeitungsthreads das Socket nicht schliesst? Leidet darunter die Performance, oder werden die Ressourcen des Servers sinnlos verbraucht? Leider habe ich vom technischen Hintergrund zu wenig Vorstellung.
Hier mein Code:
zuerst die Serverschleife:
Dann der Bearbeitungsthread:
Nochmals meine Fragen:
Danke! Georg
Der Server horcht in einer while Schleife auf Anfragen aus dem Netz. Wenn eine Anfrage ankommt, wird in dieser while-Schleife in einem neuen Thread eine Bearbeitungsklasse gestartet. In der Bearbeitungsklasse lese ich die Daten verarbeite sie zu einem Ergebnis (hier XML) und will diese zusammen mit einem http-Header an den Client zurückschicken.
Die Daten kommen aber nur dann zuverlässig beim Client an, wenn ich nach dem out.write();out.flush(); eine recht lange Zeit warte. Ich habe deshalb eine sleep-Funktion an dieser Stelle eingebaut.
Wenn ich diese Zeit zu kurz wähle, kommen beim Client nur Bruchstücke zufälliger Länge der zu übertragenden Daten an.
Ich kenne ein solches Problem aus einer reinen C++ Client-Server –Anwendung. Dort hatten wir allerdings kein http-Protokoll verwendet. Wir hatten damals vereinbart, dass der Empfänger immer ein Quittungsbyte an den Sender zurückschickt, wenn er die Daten vollständig erhalten hatte; der Sender musste dann solange warten.
Aber wie kann man das mit dem http_Protokoll machen?
Die sleep-Funktion ist ja nur eine dumme Krücke, die bestimmt nicht unter allen Voraussetzungen rausreicht….
Eine andere Lösung ist, das Socket nicht zu schliessen. Das habe ich auch ausprobiert. Aber was passiert, wenn der Server in den Bearbeitungsthreads das Socket nicht schliesst? Leidet darunter die Performance, oder werden die Ressourcen des Servers sinnlos verbraucht? Leider habe ich vom technischen Hintergrund zu wenig Vorstellung.
Hier mein Code:
zuerst die Serverschleife:
Code:
private void startServing()
{
while ( server != null && shutdown.value == false)
{
Socket client = null;
try
{
client = server.accept();
Thread t = new Thread( new Bearbeitung(client,this.config));
t.start();
}
catch ( IOException e )
{
if ( client != null )
try { client.close();
}
catch ( IOException e2 ) { e2.printStackTrace(); }
client = null;
}
}
Dann der Bearbeitungsthread:
Code:
public class Bearbeitung implements Runnable
{
private Socket client;
private RkConfig config = null;
public Bearbeitung(Socket s, RkConfig conf)
{
client = s;
config = conf;
}
public void run() {
if (client != null) {
byte[] abErg = null;
try {
HttpInput input = new HttpInput(client.getInputStream());
OutputStream out = client.getOutputStream();
input.readHttp(); //
String strData = input.getDataString();
strData = strData.trim();
// jetzt Daten verarbeiten:
abErg = datenVerarbeiten(strData);
// einen Http-Header als AsciiByte-Array erstellen:
HttpHeaders httphead = new HttpHeaders();
httphead.setContentlength(abErg.length);
byte[] abHead = httphead.writeHeaderToAsciiByteArray();
// den Http-Header verschicken
out.write(abHead);
// Ergebnis verschicken.
out.write(abErg);
out.flush();
// nur wenn ich hier lange warte, kommen beim Client die Daten
// zuverlässig an!
Thread.sleep(50000);
System.out.println("\r\nDaten an Client verschickt.");
}
catch (IOException e) {e.printStackTrace();}
catch (InterruptedException e) {e.printStackTrace();}
finally
{
try
{
// genauso, wenn ich dieses Close wegnehme, funktioniert die
// Datenübertragung...
client.close();
}
catch (IOException e) {e.printStackTrace();}
client = null;
}
}
}
}
Nochmals meine Fragen:
- Verbrauche ich die Ressourcen des Servers, wenn serverseitig die Sockets nicht geschlossen werden?
- Gibt es eine andere Möglichkeit, festzustellen, wann der Client alle Daten empfangen hat, bzw. eine andere Möglichkeit, die Daten zu verschicken, so dass ich das Socket schliessen kann!?
Danke! Georg