Note that there are some explanatory texts on larger screens.

plurals
  1. POPrintWriter vs DataOutputStream, weird behavior
    text
    copied!<p>I'm creating a server/client model to send an image file from the server to the client. There's only ONE socket involved (all data are sent through it).<br> The server first sends the size of the image file, then sends the file data in bytes through a BufferedOutputStream. The client first receives the size of the file(size), creates a byte[size] imageBytes, then writes the received file data into imageBytes through a BufferedInputStream.</p> <p>Seems straight forward. The trouble happens when I send file size in different ways.</p> <p><strong>Way 1: using DataOutputStream and DataInputStream to send and receive file size as int.</strong></p> <p><strong>Way 2: using a PrintWriter to println(file size), then flush; using a BufferedReader to readLine().</strong></p> <p><strong>Way 1 works fine. But Way 2 sends the image file incorrectly.</strong> </p> <p>I wonder if this is because BufferedReader still keeps its buffer after reading, and the buffer is subsequently read by the BuffereInputStream.</p> <p>Here are the codes:</p> <p>Server:</p> <pre><code> package test; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; public class TestServer { public static void main(String[] args){ try { ServerSocket serverSocket = new ServerSocket(9090); Socket ss = serverSocket.accept(); System.out.println("Client connected!"); File file = new File("ServerFiles/Songs/Covers/album1.jpg"); //Change this path to your own path BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); byte[] imageBytes = new byte[(int) file.length()]; bis.read(imageBytes); bis.close(); //Way 1------------------------------------------------------------- DataOutputStream dos = new DataOutputStream(ss.getOutputStream()); dos.writeInt((int) file.length()); System.out.println("dos wrote "+file.length()); //End Way 1--------------------------------------------------------- //Way 2------------------------------------------------------------- // PrintWriter pw = new PrintWriter(ss.getOutputStream()); // pw.println(file.length()); // pw.flush(); // System.out.println("pw flushed!"); //End Way 2--------------------------------------------------------- BufferedOutputStream bos = new BufferedOutputStream(ss.getOutputStream()); bos.write(imageBytes); bos.flush(); System.out.println("bos flushed!"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } </code></pre> <p>Client:</p> <pre><code> package test; import java.io.BufferedInputStream; import java.io.DataInputStream; import java.io.IOException; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; public class TestClient extends JFrame{ Socket cs; ImageIcon imageIcon; public static void main(String[] args){ try { Socket socket = new Socket(InetAddress.getLocalHost(), 9090); new TestClient(socket); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public TestClient(Socket cs) throws IOException{ this.cs = cs; init(); } private void init() throws IOException{ imageIcon = getImageIcon(); JLabel jl = new JLabel(imageIcon); JPanel content = (JPanel) this.getContentPane(); content.add(jl); this.setSize(600,400); this.setVisible(true); } private ImageIcon getImageIcon() throws IOException{ //Way 1------------------------------------------------------------- DataInputStream dis = new DataInputStream(cs.getInputStream()); int size = dis.readInt(); System.out.println("size="+size); //End Way 1--------------------------------------------------------- //Way 2------------------------------------------------------------- // BufferedReader br = new BufferedReader(new InputStreamReader(cs.getInputStream())); // int size = Integer.parseInt(br.readLine()); // System.out.println("size="+size); //Print size //End Way 2--------------------------------------------------------- BufferedInputStream bis = new BufferedInputStream(cs.getInputStream()); System.out.println("bis.available()="+bis.available()); //Print bis.available() byte[] imageBytes = new byte[size]; bis.read(imageBytes); return new ImageIcon(imageBytes); } } </code></pre> <p>Outputs:</p> <p>Way 1:</p> <p>Server:</p> <pre><code>Client connected! dos wrote 23215 bos flushed! </code></pre> <p>Client:</p> <pre><code>size=23215 bis.available()=23215 </code></pre> <p>Way 2:</p> <p>Server:</p> <pre><code>Client connected! pw flushed! bos flushed! </code></pre> <p>Client:</p> <pre><code>size=23215 bis.available()=6837 </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload