2011-01-03 3 views
1

Ich versuche, ein Java-Programm für Windows zu schreiben, die Kommunikation mit einem Server-Programm auf einem fremden Rechner beteiligt.Mein Programm erfolgreich mit dem Server verbindet, schreibt erfolgreich ein Byte-Array und wartet auf eine Antwort.Java-Client-Server senden Bytes Empfänger hört unbegrenzt

Ich weiß, dass der Server Bytes (die Antwort) zurück zu mir Byte für Byte druckt. Ich habe versucht, ein DataInputStream-Objekt mit verschiedenen Methoden (lesen, readByte usw.), ich habe versucht, ein BufferedReader-Objekt mit seinen Methoden (lesen, readLine usw.), aber alle Reader-Objekte und verschiedene Methoden, die ich verwendet habe Alle haben das gleiche Problem.

Die Bytes werden erfolgreich gelesen (jedes Mal, wenn ein Byte oder Bytes gelesen werden, kann ich sie auf die Konsole drucken, und sie sind das, was ich von ihnen erwarte). Das Problem ist, dass mein Leser nicht weiß, wann er aufhören soll zu lesen. Selbst wenn der Server alle seine Bytes gesendet hat, wartet die Reader-Funktion an meinem Ende auf unbegrenzte Zeit auf mehr Daten, und so hängt das Programm an der Lesefunktion.

Dieses Problem scheint alle Techniken zu beeinflussen, die ich ausprobiert habe. Ich habe Tests mit einem einfachen Client-Programm und einem Server-Programm durchgeführt, die jeweils etwa 40 oder 50 Zeilen lang sind, wobei der Client sich mit dem Server verbindet und einige Bytes dorthin sendet. Alle Techniken, die ich für den Serverleser ausprobiert habe, führen zu dem gleichen Problem, das oben erwähnt wurde (der Server hängt sich ab und wartet auf weitere Eingaben vom Client, obwohl er alle seine Daten gesendet hat).

Ich bin wirklich verzweifelt für etwas Hilfe zu diesem Thema. Es ist wichtig, dass ich dieses Programm in Kürze fertigstelle, und es ist im Wesentlichen komplett, abgesehen von diesem Kommunikationsproblem. Jede Hilfe wird sehr geschätzt!

-ROB

--EDIT--

Am Ende I für einen Algorithmus siedelt, die das Lesen der Bytes endet durch die Anzahl der Nachrichtensegmente zu verfolgen, die gelesen worden sind (Segmente Begrenzt durch zwei Nullwerte: 00) und vergleichen Sie das mit der Anzahl der erwarteten Segmente (übergeben an die Lesefunktion als Argument). Es ist keine ideale Methode, aber es funktioniert, und ich habe keine Zeit mehr, an dem Programm zu arbeiten.

Vielen Dank für Ihre Hilfe!

+0

Schließen Sie Ihre Streams? – npinti

+0

Ich habe versucht, das Writer-Objekt auf dem Client-Ende nach dem Senden der Daten in den Client-Server-Testprogrammen zu schließen, und es funktionierte, aber der Server verursachte dann eine Laufzeitausnahme, die besagt, dass die Verbindung geschlossen wurde, als es versuchte, ein DataOutputStream-Objekt zu erstellen um eine Antwort an den Kunden zu schreiben. Aber im eigentlichen Programm, das ich schreiben möchte, habe ich keine Kontrolle darüber, was der Server macht oder nicht tut. – Rob

+0

Auch das Senden der Länge der Daten im Voraus ist keine Option, da der Server, den ich kontaktiere, dies nicht tut, und ich habe keine Kontrolle über den Servercode. – Rob

Antwort

0

Eine andere Option (nicht so toll, aber es klingt wie Sie vielleicht sein) ist zu versuchen, auf die empfangenen Daten zu handeln. Wenn Sie beispielsweise ein serialisiertes Objekt erhalten, könnten Sie versuchen, es zu deserialisieren. Wenn es gelingt, haben Sie alle Ihre Daten erhalten. Wenn nicht, versuchen Sie, etwas mehr zu lesen.

Können Sie uns mehr darüber sagen, welche Art von Daten Sie erhalten? Gibt es in den Daten etwas, das Sie überprüfen können, um festzustellen, ob die Nachricht vollständig ist?

+0

Das Programm ist eigentlich eine Implementierung des Otway-Rees Sicherheitsprotokolls. 3 Beteiligte: ClientA, ClientB und Server. A und B möchten miteinander kommunizieren, daher verwenden sie den Server, um sie zu authentifizieren, und stellen einen Sitzungsschlüssel bereit, den sie beide für die Kommunikation verwenden können. Es ist ein Hochschulabschluss für das letzte Jahr, und meine Implementierungen müssen mit den Referenzimplementierungen meiner Dozenten kompatibel sein. Die herumgereichten Nachrichten werden unter Verwendung von NT-Codierung (Null-Terminated-Codierung) codiert. Jeder Teil der Nachricht endet mit 00. Aber es kann eine variable Anzahl von Teilen zu einer Nachricht geben. Hmm ... – Rob

+0

Wenn Sie eine variable Anzahl von Teilen sagen, gibt es im Protokoll keine vorhergehende Angabe über die tatsächliche Anzahl der Teile, die ankommen werden? – DaveC

+0

Nun, ja, tatsächlich. Das ist ein guter Punkt. Wenn die Nachrichten entsprechend gesendet werden, sollte eine feste Anzahl von NT-codierten Segmenten in der Nachricht vorhanden sein. Es lohnt sich, einen Blick darauf zu werfen, aber ich kann nicht helfen, fühle aber, dass es einfach falsch ist. Ich sollte wirklich in der Lage sein, eine generische Funktion zum Lesen von Daten von einer anderen Entität zu haben. – Rob

1

Sie, die die Endbedingung definiert.

Ein häufiger, einfacher Fall ist das einfache Schließen der Verbindung (dies ist die Definition des Druckprotokolls P9100). Der Lesevorgang sollte jetzt -1 zurückgeben.

Ansonsten können Sie

  • Präfix Ihre Daten mit einer Länge. Der Server stoppt den Lesevorgang, nachdem die n Bytes
  • die Daten mit einem dedizierten Byte beendet haben. Der Server hört auf zu empfangen, wenn das Marker-Byte gefunden wird.

Ist das dein Problem oder habe ich es falsch verstanden?

1

Sie brauchen entweder den Server, um die Verbindung zu schließen, oder Sie müssen anhand der Daten feststellen können, dass die Nachricht des Servers beendet ist - vielleicht mithilfe eines speziellen Bytes (z. B. ein Nullbyte) oder durch Senden der Länge von die Daten vor den Daten selbst.

Ansonsten kann die Anwendung den Unterschied zwischen dem Server, der seine Daten gesendet hat (und dem Warten auf die nächste Anfrage), und dem Server, der mitten in dem Senden seiner Daten pausiert, unterscheiden.

0

Damit Ihre Anwendung weiter ausgeführt werden kann, können Sie die Antwortdaten in einem separaten Thread lesen.

Wenn es wirklich keine andere Möglichkeit gibt zu wissen, wann die Nachricht beendet ist, können Sie ein Timeout verwenden. Wenn Sie also Daten erhalten und Sie nicht mehr für 100 ms oder 1 Sekunde erhalten haben, können Sie davon ausgehen, dass Sie alles haben.

Eine bessere Alternative ist, dass Sie Ihren Code schreiben, damit er nicht wissen muss, wann das Ende der Nachricht ist. Es könnte jede "Antwort" so verarbeiten, wie sie sie erhält, und sie als Streaming-Ereignisse behandeln, wenn sie ankommen.

Wie die Daten zurückkommen, scheint es anzunehmen, dass Sie nicht wissen müssen, wann die Daten vollständig sind.

Verwandte Themen