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: 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?
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*
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
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!
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);
int read =0;System.out.println("Start lesen");while((read = in.read(buffer,0, bufferSize))!=-1){//<- Zeile 90System.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)
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
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.
@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:
publicclassTest{publicstaticvoidmain(String[] args)throwsException{newThread(newServer()).start();// Server starten// Rest ist ClientThread.sleep(1000);Socket skt =newSocket("localhost",3456);PrintWriter out =newPrintWriter(skt.getOutputStream(),true);BufferedReader in =newBufferedReader(newInputStreamReader(skt.getInputStream()));
out =newPrintWriter(newOutputStreamWriter(skt.getOutputStream()));StringBuilder st =newStringBuilder();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();}}classServerimplementsRunnable{publicvoidrun(){try{serve();}catch(Exception e){
e.printStackTrace();}}publicvoidserve()throwsException{ServerSocket socket =newServerSocket(3456);Socket skt = socket.accept();BufferedReader in =newBufferedReader(newInputStreamReader(skt.getInputStream()));PrintWriter out =newPrintWriter(newOutputStreamWriter(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 =newString[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());}}
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