Buffer size

Taramsis

Bekanntes Mitglied
Hi Leute,

ich habe einen kleinen Server implementiert. Hier habe ich die Möglichkeit über einem Client Strings zu versenden.

Mein Problem ist es nun, dass ich ein String der Länge von 30203 versende und beim Server nur 24525 Zeichen ankommen:

char[] buffer = new char[30203];
int charLength = in.read(buffer, 0, 30203);
inputLine = new String(buffer, 0, charLength);

System.out.println("INPUTLENGTH: " + inputLine.length()); // sind dann 24525 ;(

Liegt es an JAVA???
 
S

SlaterB

Gast
vielleicht sind erst ein Teil der Zeichen da, warte 1 sec vor dem Lesen,
bzw. die allgemeine Lösung ist, in einer Schleife solange zu lesen bis -1 für Ende kommt oder das Lesen blockiert weil aktuell nichts mehr zu lesen ist und auf das nächste gewartet wird,
alles was bis dahin zusammengetragen wurde dürfte dann 30203 sein
 

FArt

Top Contributor
Vemutlich puffert der Sender die Daten. Ein close oder flush auf dem Stream sollte dafür sorgen, dass der Puffer geleert wird.
 

Taramsis

Bekanntes Mitglied
@FArt: Der Client führt einen flush aus!
@Marco13: Ich lasse die das String vor dem versenden ausgeben und es sind alle Zeichen enthalten!
@Slater: Wie genau meinst du das? Soll ich vor
Java:
int charLength = in.read(buffer, 0, bufferSize);
ein wait einbauen?
Wie kann ich den eine Schleife sagen er solle lessen bis -1 kommt? Man müßte doch dann eine -1 mitgeben?:oops:
 

Volvagia

Top Contributor
Wie kann ich den eine Schleife sagen er solle lessen bis -1 kommt? Man müßte doch dann eine -1 mitgeben?:oops:

Reads characters into a portion of an array.
This method implements the general contract of the corresponding read method of the Reader class. As an additional convenience, it attempts to read as many characters as possible by repeatedly invoking the read method of the underlying stream. This iterated read continues until one of the following conditions becomes true:

The specified number of characters have been read,
The read method of the underlying stream returns -1, indicating end-of-file, or
The ready method of the underlying stream returns false, indicating that further input requests would block.
If the first read on the underlying stream returns -1 to indicate end-of-file then this method returns -1. Otherwise this method returns the number of characters actually read.
Subclasses of this class are encouraged, but not required, to attempt to read as many characters as possible in the same fashion.

Ordinarily this method takes characters from this stream's character buffer, filling it from the underlying stream as necessary. If, however, the buffer is empty, the mark is not valid, and the requested length is at least as large as the buffer, then this method will read characters directly from the underlying stream into the given array. Thus redundant BufferedReaders will not copy data unnecessarily.

Overrides: read(...) in Reader
Parameters:
cbuf Destination buffer
off Offset at which to start storing characters
len Maximum number of characters to read
Returns:
The number of characters read, or -1 if the end of the stream has been reached
Throws:
IOException - If an I/O error occurs


Ich frag mich, was das für ein String mit 30k Zeichen ist.
Was steht denn in charLength nach dem Lesen drinnen? *frage wiederhohl*
 
S

SlaterB

Gast

Taramsis

Bekanntes Mitglied
Ich hab nun folgendes probiert:

Java:
char[] buffer = new char[30203];

int charLength = 0;
while ((inputLine = in.readLine()).equals("-1")) {
charLength = in.read(buffer, 0, 30203);
}
inputLine = new String(buffer, 0, charLength);

Ich hab mal fogendes probiert! Hängt nun in der Schleife fest!???:L
 
S

SlaterB

Gast
ohne Denken funktioniert es leider nicht,

dass beim Lesen von Zeilen auf null geprüft wird, habe ich doch gesagt bzw. kann man einfach dem kopierten Code entnehmen,
welch verrückte Idee, auf einen String aus zwei Zeichen "-1" zu vergleichen,

selbst wenn irgendwas in der Richtung funktionierte, dann würde in inputLine die Zeilen also die Daten geschrieben,
inputLine ignorierst du danach aber, und liest nochmal neu aus dem Stream, diesmal als Array,
damit gingen Daten verloren, denn bei jedem Lesen kommt was neues, nichts wird erst in den String inputLine geschrieben, danach dann noch in dein Array,

naja, aus solchen Sätzen von mir ist das wohl nicht zu verstehen, du weißt nichts über Streams und kopierst irgendwas zusammen, das wird nix,
kopiere NUR fertigen Code von irgendwo, aber auf nicht irgendwas direkt darin verändern, nur die Verwendung des Array-Inhalts, die Quelle des Streams usw.,

BufferedReader mit String-Zeilen magst du wahrscheinlich nicht,
hier ein Beispiel nur mit Arrays, da sieht man sogar die -1..
Java I/O Streams
beachte wie das (relativ kleine) Array mehrmals eingelesen und gleich weiterverarbeitet wird,
denn beim nächsten Schleifendurchlauf wird das Array ja neu befüllt
 

Taramsis

Bekanntes Mitglied
Danke für deine Geduld!:oops:

Ich bin noch ein totaler noob!

Hier nochmal ein Überblick:

Danke für die Rückmeldung!
Das einzige was ich anders mache ist die Benutzung eines "PrintWriter":

Client:

[Java]PrintWriter out = new PrintWriter(skt.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(skt.getInputStream()));
out = new PrintWriter(new OutputStreamWriter(skt.getOutputStream()));
out.print("String ;" + "String ;" + "String ;" + "String \n" + "String mit 30203 Zeichen");
out.flush();[/Java]

Close führe ich noch nicht aus da eine Antwort erwartet wird!

Server:

[Java]BufferedReader in = new BufferedReader(new InputStreamReader(skt.getInputStream()));
PrintWriter out = new PrintWriter(new OutputStreamWriter(skt.getOutputStream()));

String split[] = Pattern.compile("; ").split(in.readLine());
String modelType = split[0];
String model = split[1];
int paramNumber = Integer.parseInt(split[2]);
String[] param = new String[paramNumber];
for (int i = 0; i < paramNumber; i++) {
param = split[i + 3];
}

int bufferSize = Integer.parseInt(split[paramNumber + 3]);
char[] buffer = new char[bufferSize];
int charLength = in.read(buffer, 0, bufferSize);
inputLine = new String(buffer, 0, charLength);[/Java]

Das meine Strings mit Semikolon getrennt usw. ist ne Vorgabe!

Nun hab ich ndie unteren vier Zeilen durch folgendes ersetzt!

Java:
int bufferSize = Integer.parseInt(split[paramNumber + 3]);
char[] buffer = new char[bufferSize];
int charLength = 0;
int read =0;
while ((read = in.read(buffer, 0, bufferSize)) != -1) {
   charLength = in.read(buffer, 0, bufferSize);
   inputLine = new String(buffer, 0, charLength);
}

Leider ohne Erfolg! Buffersize wir ja ausgelesen und ist 30203!
 
S

SlaterB

Gast
ändere deinen Code bitte in
Java:
int read =0;
System.out.println("Start lesen");
while ((read = in.read(buffer, 0, bufferSize)) != -1) {
   System.out.println("habe gelesen: "+read);
}
System.out.println("fertig mit lesen");
und poste die Ausgaben
 

Murray

Top Contributor
Die read-Methode liefert zurück, wieviele Bytes gelesen wurde. Das können maximal soviele sein, wie als dritter Parameter übergeben wurde; es können aber auch weniger sein. -1 kommt, wenn es nichts mehr zu lesen gibt.
Falls weniger Daten geliefert werden als angefordert, muss man im nächsten Durchgang eben weiter lesen. Das Ergebnis der nächsten Leseoperation muss in diesem Fall an die bisher gelesenen Daten angehängt werden. Dazu gibt es den zweiten Parameter der read-Methode, mit dem man angeben kann, an welcher Stelle des Ziel-Arrays die gerade gelesenen Daten kopiert werden sollen.

Daher:
Java:
int read = 0;
while ((read = in.read(buffer, read, bufferSize)) != -1);
 

Taramsis

Bekanntes Mitglied
@murray:

Wenn ich nun folgendes habe:

Java:
int read =0;
System.out.println("Start lesen");
while ((read = in.read(buffer, 0, bufferSize)) != -1) {  //<- Zeile 90
   System.out.println("habe gelesen: "+read);
}
System.out.println("fertig mit lesen");

Kommt folgende Ausgabe:

Start lesen
habe gelesen: 24525
Exception in thread "Thread-4" java.lang.IndexOutOfBoundsException
at java.io.BufferedReader.read(BufferedReader.java:256)
at jamala.NetworkThread.run(NetworkThread.java:90)
at java.lang.Thread.run(Thread.java:619)
 
S

SlaterB

Gast
da der Client offen bleibt könntest du die read-Anzahlen addieren, und die Schleife beenden, wenn 30203 Zeichen gelesen wurden,
dass eine Exception kommt, ist bisschen merkwürdig, auch wenn du anscheinend nicht ganz Murrays Code gepostet hast

------

da du so fleißig ausprobierst, wäre was anderes vielleicht leichter:
der Client schreibt den 30203-String, danach Zeilenumbruch "\n" und flush()

im Server liest du eine weitere Zeile ein:
inputLine = in.readLine();
fertig, kein Buffer, keine Schleife,
wenn du ein char[] brauchst, kannst du das auch aus dem String generieren


---
ganz nebensächlich:
übrigens definierst du im Client out 2x, und generell ist es besser, immer erst den OutputStream anzulegen als den InputStream
 
Zuletzt bearbeitet von einem Moderator:

Taramsis

Bekanntes Mitglied
D.H. du meinst folgendes?

Client:
Java:
out.print("String ;" + "String ;" + "String ;" + "String" + "\n" +  "String mit 30203 Zeichen" + "\n");
out.flush();
 

Murray

Top Contributor
da der Client offen bleibt könntest du die read-Anzahlen addieren, und die Schleife beenden, wenn 30203 Zeichen gelesen wurden,
dass eine Exception kommt, ist bisschen merkwürdig, auch wenn du anscheinend nicht ganz Murrays Code gepostet hast

Stimmt, mir fehlt wohl noch ein Kaffee - natürlich ergibt sich die Position durch Addition der bisherigen reads. Außerdem braucht man nur noch (Gesamtlänge - bereits gelesen) Zeichen zu lesen.
Dann sollte man das Lesen noch beenden, wenn bereits alle Daten gelesen wurden.

Java:
int pos = 0;
int read = 0;
while ( (pos < bufferSize) && (read = in.read(buffer, pos, (bufferSize-pos))) != -1) {
  pos+=read;
}
 

Taramsis

Bekanntes Mitglied
Leider passiert gar nichts! "2222" wird nicht ausgegeben! Ist das zu viel für Ihn?


Java:
System.out.println("1111");
inputLine = in.readLine();
System.out.println("2222");
 
S

SlaterB

Gast
@Murray
wenn read am Anfang 0 ist und es nur zwei Durchläufe gibt, dann sollte es bisher doch auch klappen, schlimmstenfalls das Array weiter vorne falsch befüllt werden,
wie es wohl zu einer Exception kommen kann?
evtl. mit einem größeren Array ausprobieren, ruhig auch mal 500.000,

den Fehler mit dem 1111, 2222 kann ich mir auch nicht erklären, alles mysteriös,

eine weitere Baustelle wäre nun testen:
sende
out.print("String ;" + "String ;" + "String ;" + "String" + "\n" + "x" + "\n");
wird "x" vor 2222 gelesen (gelesenen String auch ausgeben)?

danach "x" im Client nach und nach durch kompliziertere Strings ersetzen, per Schleife auch 30000 "x" zusammenfassen
und alles mögliche, wenn das geht aber der andere String nicht, dann diesen genauer untersuchen,
z.B. nur den ersten char davon senden, kommt an? dann 2, 3 usw.,
kommt irgendwann ein Fehler?
wenn erst nach 24525, dann kann man wieder an einen Übertragungsfehler denken, bei kleineren Werten doch irgendwie vom Inhalt abhängig?
aber ich rate nur, kann ich mir eigentlich nicht vorstellen

wobei ich das auch nicht schreiben sollte ohne selber zu testen, ergo:
Java:
public class Test  {
    public static void main(String[] args)   throws Exception  {
        new Thread(new Server()).start(); // Server starten

        // Rest ist Client
        Thread.sleep(1000);
        Socket skt = new Socket("localhost", 3456);
        PrintWriter out = new PrintWriter(skt.getOutputStream(), true);
        BufferedReader in = new BufferedReader(new InputStreamReader(skt.getInputStream()));
        out = new PrintWriter(new OutputStreamWriter(skt.getOutputStream()));
        StringBuilder st = new StringBuilder();
        for (int i = 0; i < 30203; i++)  {
            st.append((char)(i + 100)); // +100, damit Zeilenumbruch nicht mit dabei
        }

        out.print("String; " + "String; " + "3; " + "30203\n" + st.toString() + "\n");
        out.flush();
    }
}


class Server  implements Runnable {
    public void run()  {
        try  {
            serve();
        }  catch (Exception e)   {
            e.printStackTrace();
        }
    }

    public void serve()   throws Exception  {
        ServerSocket socket = new ServerSocket(3456);
        Socket skt = socket.accept();
        BufferedReader in = new BufferedReader(new InputStreamReader(skt.getInputStream()));
        PrintWriter out = new PrintWriter(new OutputStreamWriter(skt.getOutputStream()));

        String split[] = Pattern.compile("; ").split(in.readLine());
        String modelType = split[0];
        String model = split[1];
        int paramNumber = Integer.parseInt(split[2]);
        String[] param = new String[paramNumber];
        for (int i = 0; i < paramNumber; i++) {
            param[i] = split[i];
        }

        int bufferSize = Integer.parseInt(split[3]);
        System.out.println("b: " + bufferSize);
        System.out.println("1111");
        String inputLine = in.readLine();
        System.out.println("2222 - " + inputLine.length());
    }
}
Ausgabe:
Code:
b: 30203
1111
2222 - 30203
funktioniert
 

Taramsis

Bekanntes Mitglied
@ Slater: schau ich mir an! Danke!

@murray:

hab dein code nun getestet

Java:
int pos = 0;
int read =0;
System.out.println("Start lesen");
while ( (pos < bufferSize) && ((read = in.read(buffer, pos, (bufferSize-pos)))!= -1) ) {
       pos+=read;
       inputLine += new String(buffer, 0, read);
       System.out.println("habe gelesen: "+read);
}
System.out.println("fertig mit lesen");
System.out.println("INPUTLENGTH: " + inputLine.length());

Ausgabe:
Start lesen
habe gelesen: 24525
habe gelesen: 5678
fertig mit lesen
INPUT: 30203

Nur das blöde ist, dass "inputline" 1 mal die 24525 Zeichen und der Rest wieder die gleichen Strings sind wobei nun bei 5678 Zeichen Schluß ist.
 
S

SlaterB

Gast
weil du im Moment aufwendig erst an den Anfang, dann an das Ende des Array schreibst,
aber jedesmal vom Anfang des Arrays liest..

lasse hier die Schleife komplett durchlaufen und lies DANACH das komplett befüllte Array in einen String,
oder wenn du bei jedem Lesen zum String hinzufügst, dann muss es wiederum das eher normale [c]in.read(buffer, 0, ..[/c] sein, also immer an den Anfang des Arrays schreiben, vorheriges überschreiben
 


Schreibe deine Antwort... und nutze den </> Button, wenn du Code posten möchtest...
Ähnliche Java Themen
  Titel Forum Antworten Datum
E JFrame + Buffer-strategy Java Basics - Anfänger-Themen 8
P Buffer und null Java Basics - Anfänger-Themen 3
S Wann buffer löschen? Java Basics - Anfänger-Themen 5
B Input/Output Data / Buffer / File Outstream Inputstream Java Basics - Anfänger-Themen 2
P Java SocketException: No buffer space available ==> Netzwerkabsturz Java Basics - Anfänger-Themen 5
P Für was werden Buffer verwendet? Java Basics - Anfänger-Themen 3
G Bild in Buffer statt temporäre Bilddatei Java Basics - Anfänger-Themen 6
J Java NIO Probleme mit Buffer Java Basics - Anfänger-Themen 2
S Buffer Ausgabe Java Basics - Anfänger-Themen 6
S Buffer - charArray bitte um Hilfe! Java Basics - Anfänger-Themen 4
U Beispiel Methode size() vom "Collection"-interface... Wie kann man sichtbar machen, was die Methode unter der Haube macht? Java Basics - Anfänger-Themen 8
S Java Client-je nach Heap Size Größe startet Applikation oder nicht Java Basics - Anfänger-Themen 4
A ArrayList - size() nur nach bestimmtem index anzeigen lassen Java Basics - Anfänger-Themen 13
S Binärer Suchbaum - Size als Variabel in innerer Klasse speichern Java Basics - Anfänger-Themen 2
R AES Key 256 Illegal Key Size auch bei Änderung der Policy Java Basics - Anfänger-Themen 3
P Butten Size Java Basics - Anfänger-Themen 1
P Listen Size stimmt nicht Java Basics - Anfänger-Themen 5
T negativ array size exception Java Basics - Anfänger-Themen 9
K Fehlermeldung: java.lang.IndexOutOfBoundsException: Index: 1, Size: 1 Java Basics - Anfänger-Themen 4
V LinkedList size() Java Basics - Anfänger-Themen 2
P Leere Arraylist hat size von 1? Java Basics - Anfänger-Themen 3
ruutaiokwu Iterator oder .size ??? Java Basics - Anfänger-Themen 6
T ArrayList size nicht gefunden Java Basics - Anfänger-Themen 3
E Höherer Index als Size in ArrayList Java Basics - Anfänger-Themen 9
E Frage zur Methode size() der Klasse ZipFile Java Basics - Anfänger-Themen 2
K List (ArrayList) und size() Methode Java Basics - Anfänger-Themen 8
G heap size vergrößern Java Basics - Anfänger-Themen 6
B Iterables und size() Java Basics - Anfänger-Themen 9
U ArrayList.size() Java Basics - Anfänger-Themen 14
E Heap Size einstellen Java Basics - Anfänger-Themen 7
B File.size() ? Java Basics - Anfänger-Themen 11
C Size JTextField in GridBagLayout Java Basics - Anfänger-Themen 2
G Static Vector gibt immer size()=0!!! Java Basics - Anfänger-Themen 3

Ähnliche Java Themen

Neue Themen


Oben