How to compress data using deflaterOutputStream by socket in Java

Viewed 46

There are two classes in my code:

public class ClientHandler {
    private Socket socket;
    private DeflaterOutputStream deflaterOutputStream;
    private BufferedReader bufferedReader;

    public ClientHandler(Socket socket) throws IOException {
        this.socket = socket;
        bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        deflaterOutputStream = new DeflaterOutputStream(socket.getOutputStream());
        StringBuilder stringBuilder = new StringBuilder();

        for (int i = 0; i < 100000; i++) {
            stringBuilder.append(String.format("%d\n", i));
        }

        deflaterOutputStream.write("start\n".getBytes());
        deflaterOutputStream.write(stringBuilder.toString().getBytes());
        deflaterOutputStream.write("end\n".getBytes());
        deflaterOutputStream.flush();

        String dataFromClient = bufferedReader.readLine();
        System.out.println(dataFromClient);
    }
}

public class Client {
    private Socket socket;
    private InflaterInputStream inflaterInputStream;
    private BufferedReader bufferedReader;
    private BufferedWriter bufferedWriter;

    public Client(Socket socket) throws IOException{
        this.socket = socket;
        bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        inflaterInputStream = new InflaterInputStream(socket.getInputStream());
        bufferedReader = new BufferedReader(new InputStreamReader(inflaterInputStream));

        int receiveCount = 0;
        while (socket.isConnected()) {
            String messageFromServer;
            if ((messageFromServer = bufferedReader.readLine()) != null && messageFromServer.equals("start")) {
                while ((messageFromServer = bufferedReader.readLine()) != null && !messageFromServer.equals("end")){
                    System.out.println(messageFromServer);
                }
                receiveCount++;
                System.out.println("I get " + receiveCount + " times data.");
                bufferedWriter.write("I get data.\n");
                bufferedWriter.flush();
            }
        }
    }
}

After executing the above code, the terminal of ClientHandler shows nothing, and the terminal of Client shows:

0
1
2
...
98787
98788

So my first question is: Why does the Client only accept 0 to 98788? Where is the remaining numbers after 98788? I am already doing a flush(). In my previous experience, when I use BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); and do bufferedWriter.flush();, it can indeed send all of the data to the Client.

I tried to replace flush() to finish(), and now the Client can receive 0 to 99999 numbers. So my second question is: What is the difference between flush() and finish()? I have read DeflaterOutputStream, but do not understand what the difference is.

Ok, now, I can send whole data by socket, But I put some code in ClientHandler below:

    deflaterOutputStream.write("start\n".getBytes());
    deflaterOutputStream.write(stringBuilder.toString().getBytes());
    deflaterOutputStream.write("end\n".getBytes());
    deflaterOutputStream.finish();

After execute, it throws a exeception: "write beyond end of stream". I can't send data after I do finish().

I thought I could re-declare deflaterOutputStream in this code above. After I add a re-declare of deflaterOutputStream , Client can accept the first part of 0 to 99999, too. But the terminal shows:

0
1
2
...
99998
99999
I get 1 times data.

Client just can accept data before clientHandler does finish() once. This is my third question: How can I send data to client more than once?

0 Answers
Related