I am making a Java program using Sockets. I can send commands to the client and client to the server. To read commands I use BufferedReader . To write them, PrintWriter But now I want to transfer the file through which socket (not just create a second connection).
First I write to the output stream how many bytes are in the file, For example, 40,000 bytes. Therefore, I am writing the number 40000 through the socket, but 78 is read on the other side of the connection.
So, I thought: BufferedReader reads more than just a line (by calling readLine() ), and so I lose a few bytes from the data files. Because they are in the buffer from the BufferedReader .
So the number 78 is the byte of the file I want to transfer.
Is this way of thinking right or wrong. If yes, then how to solve this problem.
I hope I have a good explanation.
Here is my code, but my default language is Dutch. Therefore, some variable name may sound non-standard.
public void flushStreamToStream(InputStream is, OutputStream os, boolean closeIn, boolean closeOut) throws IOException { byte[] buffer = new byte[BUFFERSIZE]; int bytesRead; if ((!closeOut) && closeIn) { // To Socket from File action = "Upload"; os.write(is.available()); // Here I write 400000 max = is.available(); System.out.println("Bytes to send: " + max); while ((bytesRead = is.read(buffer)) != -1) { startTiming(); // Two lines to compute the speed os.write(buffer, 0, bytesRead); stopTiming(); // Speed compution process += bytesRead; } os.flush(); is.close(); return; } if ((!closeIn) && closeOut) { // To File from Socket action = "Download"; int bytesToRead = -1; bytesToRead = is.read(); // Here he reads 78. System.out.println("Bytes to read: " + bytesToRead); max = bytesToRead; int nextBufferSize; while ((nextBufferSize = Math.min(BUFFERSIZE, bytesToRead)) > 0) { startTiming(); bytesRead = is.read(buffer, 0, nextBufferSize); bytesToRead -= bytesRead; process += nextBufferSize; os.write(buffer, 0, bytesRead); stopTiming(); } os.flush(); os.close(); return; } throw new IllegalArgumentException("The only two boolean combinations are: closeOut == false && closeIn == true AND closeOut == true && closeIn == false"); }
Here is the solution:
Thanks to the suggestion of James
I think laginimaineb anwser was part of the solution.
Read the commands.
DataInputStream in = new DataInputStream(is); // Originally a BufferedReader // Read the request line String str; while ((str = in.readLine()) != null) { if (str.trim().equals("")) { continue; } handleSocketInput(str); }
Now flushStreamToStream:
public void flushStreamToStream(InputStream is, OutputStream os, boolean closeIn, boolean closeOut) throws IOException { byte[] buffer = new byte[BUFFERSIZE]; int bytesRead; if ((!closeOut) && closeIn) { // To Socket from File action = "Upload"; DataOutputStream dos = new DataOutputStream(os); dos.writeInt(is.available()); max = is.available(); System.out.println("Bytes to send: " + max); while ((bytesRead = is.read(buffer)) != -1) { startTiming(); dos.write(buffer, 0, bytesRead); stopTiming(); process += bytesRead; } os.flush(); is.close(); return; } if ((!closeIn) && closeOut) { // To File from Socket action = "Download"; DataInputStream dis = new DataInputStream(is); int bytesToRead = dis.readInt(); System.out.println("Bytes to read: " + bytesToRead); max = bytesToRead; int nextBufferSize; while ((nextBufferSize = Math.min(BUFFERSIZE, bytesToRead)) > 0) { startTiming(); bytesRead = is.read(buffer, 0, nextBufferSize); bytesToRead -= bytesRead; process += nextBufferSize; os.write(buffer, 0, bytesRead); stopTiming(); } os.flush(); os.close(); return; } throw new IllegalArgumentException("The only two boolean combinations are: closeOut == false && closeIn == true AND closeOut == true && closeIn == false"); }
Martine.