United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-4206909 want java.util.zip to work for interactive use (Z_SYNC_FLUSH)
JDK-4206909 : want java.util.zip to work for interactive use (Z_SYNC_FLUSH)

Details
Type:
Enhancement
Submit Date:
1999-01-28
Status:
Closed
Updated Date:
2012-01-25
Project Name:
JDK
Resolved Date:
2012-01-25
Component:
tools
OS:
windows_nt,generic,windows_98
Sub-Component:
jar
CPU:
x86,generic
Priority:
P4
Resolution:
Fixed
Affected Versions:
1.1.7,1.1.8,1.2.0,1.3.0,1.4.2
Fixed Versions:

Related Reports
Duplicate:
Duplicate:
Relates:
Relates:
Relates:

Sub Tasks

Description

Name: zl72593			Date: 01/28/99

=20
To establish an encrypted network connection for _interactive_
use you need to compress the stream _before_ encryption because
an already encrypted stream is not compressible.

Today it is not possible to reuse java.util.zip for compression
because the Java VM calls deflate() in the libz with
Z_NO_FLUSH (and Z_FINISH for EOF) only. This means that in most
cases the deflate() does not emit enough data for the
decompressor to reassemble the complete data packet because
it waits for more input.

This is what the deflate() parameter Z_SYNC_FLUSH is for.
It enables the inflate() of the receiver to create the full
data packet. This will decrease the compression ration slightly=20
but will allow to reuse java.util.zip for interactive use.

Please note that this is _not_ Z_FULL_FLUSH, which would tell
deflate() to do a full reset of the compressor.
(Review ID: 52795)
======================================================================

Name: krT82822			Date: 10/29/99


N/A API deficiency
The java.util.zip routines do not support the zlib functionality of
Z_SYNC_FLUSH. This makes it impossible to write a client-server application
where the client and server pass each other messages along a compressed stream,
as you need to be able to compress a message (given the current dictionary, not
just starting with a new one), flush and byte-align the output, and then send
the message across the socket. This is possibile with the c implemention of
zlib, as the Z_SYNC_FLUSH will flush and byte-align the output of the current
compression operation.
(Review ID: 97225)
======================================================================

Name: mc57594			Date: 01/05/2000


C:\>java -version
java version "1.2"
Classic VM (build JDK-1.2-V, native threads)


I am trying to develop a client/server application using sockets. To improve
performance I am trying to zip de data sent to the socket, using
java.util.zip.DeflaterOutputStream and java.util.zip.inflaterInputStream, but
the application stops when the client or the server write something in the
output stream.

Without zip stream it works fine.

Here is the code of client:

import java.net.*;
import java.io.*;
import java.util.zip.*;

public class SocketClientApp
{
  public static void main( String [] args ) throws IOException
  {
    Socket clientSocket = null;
    PrintWriter out     = null;
    BufferedReader in   = null;

    try
    {
      clientSocket = new Socket( "localhost", 4444 );
      out = new PrintWriter( new DeflaterOutputStream(
                                 clientSocket.getOutputStream() ), true );
      in  = new BufferedReader( new InputStreamReader( new InflaterInputStream(
                                 clientSocket.getInputStream() ) ) );

      BufferedReader stdIn = new BufferedReader( new InputStreamReader(
                                                               System.in ) );

      String fromServer, fromUser;
      while( ( fromServer = in.readLine() ) != null )
      {
        System.out.println( "Server said: " + fromServer );
        fromUser = stdIn.readLine();
        if( fromUser != null )
          out.println( fromUser );

        if( fromUser.equals( "TChau!" ) )
          break;
      }

      out.close();
      in.close();
      stdIn.close();
      clientSocket.close();
    }
    catch( UnknownHostException e)
    {
      e.printStackTrace();
    }
    catch( IOException e )
    {
      e.printStackTrace();
    }
  }
}

Here is the code of the server Thread:

import java.net.*;
import java.io.*;
import java.util.zip.*;

public class SocketServerThread extends Thread
{
   private Socket clientSocket;

   public SocketServerThread( Socket clientSocket )
   {
      super( "MultiServerThread" );

      this.clientSocket = clientSocket;
   }

   public void run()
   {
      try
      {
         PrintWriter out   = new PrintWriter( new DeflaterOutputStream(
                                      clientSocket.getOutputStream() ), true );
         BufferedReader in = new BufferedReader( new InputStreamReader( new
InflaterInputStream( clientSocket.getInputStream() ) ) );

         String inputLine, outputLine;

         outputLine = "Server: Hello!";
         out.println( outputLine );

         while( ( inputLine = in.readLine() ) != null )
         {
            System.out.println( "Received: " + inputLine );
            if( inputLine.equals( "TChau!" ) )
              break;
            outputLine = "You typed: " + inputLine;
            out.println( outputLine );
         }

         in.close();
         out.close();
         clientSocket.close();
      }
      catch( IOException e )
      {
         e.printStackTrace();
      }
   }
}

Here is the server application:

import java.net.*;
import java.io.*;

public class MultiSocketServerApp
{
   static public void main( String [] args ) throws IOException
   {
      ServerSocket serverSocket = null;
      try
      {
        serverSocket = new ServerSocket( 4444 );
      }
      catch( IOException e )
      {
        e.printStackTrace();
      }

      while( true )
      {
        Socket clientSocket = null;
        try
        {
           clientSocket = serverSocket.accept();
           SocketServerThread newThread = new SocketServerThread(
clientSocket );
           newThread.start();
        }
        catch( IOException e )
        {
           e.printStackTrace();
           System.exit(-1);
        }
      }
   }
}
(Review ID: 98981)
======================================================================

Name: krC82822			Date: 01/27/2001


java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)

There is no way to do a partial or sync flush of java.util.zip.Deflater. A
partial flush is required when you want to send multiple compressed segments on
a single stream such that they use the same compression parameters and
dictionary. In particular, it is needed to properly implement the compression
mode of Secure Shell.

Add a deflate() method with the following signature:
  public synchronized int deflate( byte[] b, int off, int len, int flush );

where flush is one of
  public static final int DEFLATER_NO_FLUSH      = 0;
  public static final int DEFLATER_PARTIAL_FLUSH = 1;
  public static final int DEFLATER_SYNC_FLUSH    = 2;
  public static final int DEFLATER_FULL_FLUSH    = 3;
  public static final int DEFLATER_FINISH        = 4;

You can make this change without breaking any existing code: when Deflater's
private field 'finish' is true, the existing deflate() methods should call the
new method with a flush argument of DEFLATER_FINISH. Otherwise they would
specify DEFLATER_NO_FLUSH.

It's actually a bit more complicated than that. If the caller supplies
DEFLATER_FINISH, you would have to call end() to update the 'finish' field.
(Review ID: 115912)
======================================================================

                                    

Comments
WORK AROUND



Name: zl72593			Date: 01/28/99

=20
Port a compressor/decompressor to Java and use that instead
of java.util.zip. To avoid porting to several platforms this
must be done in 100% Java which will decrease the compressor
speed.
======================================================================
                                     
2004-09-11
EVALUATION

A flush with Z_SYNC_FLUSH is all we need.
                                     
2009-02-20



Hardware and Software, Engineered to Work Together