View Javadoc
1   package com.liviutudor.rmi.io.gzip;
2   
3   import java.io.IOException;
4   import java.io.InputStream;
5   import java.io.OutputStream;
6   import java.net.Socket;
7   import java.net.UnknownHostException;
8   import java.util.zip.GZIPInputStream;
9   import java.util.zip.GZIPOutputStream;
10  
11  /**
12   * Socket which uses gzip to compress the data sent over the wire.
13   *
14   * @author Liviu Tudor http://about.me/liviutudor
15   */
16  class GzipSocket extends Socket {
17      /** Wrapper for the socket input stream. */
18      private GZIPInputStream  inputStream;
19  
20      /** Wrapper for the socket output stream. */
21      private GZIPOutputStream outputStream;
22  
23      /**
24       * Creates a socket which connects to the given host on the given port.
25       *
26       * @param host
27       *            Host to connect to
28       * @param port
29       *            Port to connect to
30       * @throws UnknownHostException
31       *             if host name or IP is wrong
32       * @throws IOException
33       *             if I/O errors occur when connecting
34       */
35      public GzipSocket(String host, int port) throws UnknownHostException, IOException {
36          super(host, port);
37      }
38  
39      @Override
40      public synchronized void close() throws IOException {
41          if (inputStream != null) {
42              inputStream.close();
43              inputStream = null;
44          }
45          if (outputStream != null) {
46              outputStream.flush();
47              outputStream.close();
48              outputStream = null;
49          }
50          super.close();
51      }
52  
53      /**
54       * Overrides the base class method for returning the input stream for this
55       * socket and returns instead the {@link #inputStream gzip-based wrapper}.
56       * Note that this is a lazy evaluation function. NOTE: The GzipInputStream
57       * blocks on creation to read the header so this function actually blocks
58       * until data is available over the wire!
59       *
60       * @return wrapper for the base class input stream
61       * @throws IOException
62       *             if I/O errors occur
63       * @see #inputStream
64       */
65      @Override
66      public synchronized InputStream getInputStream() throws IOException {
67          if (inputStream == null) {
68              inputStream = new GZIPInputStream(super.getInputStream());
69          }
70          return inputStream;
71      }
72  
73      /**
74       * Overrides the base class method for returning the output stream for this
75       * socket and returns instead the {@link #outputStream gzip-based wrapper}.
76       *
77       * @return wrapper for the base class output stream
78       * @throws IOException
79       *             if I/O errors occur
80       * @see #outputStream
81       */
82      @Override
83      public synchronized OutputStream getOutputStream() throws IOException {
84          if (outputStream == null) {
85              outputStream = new GZIPOutputStream(super.getOutputStream());
86          }
87          return outputStream;
88      }
89  
90      @Override
91      public void shutdownInput() throws IOException {
92          // TODO: what do we need to do here?
93          super.shutdownInput();
94      }
95  
96      @Override
97      public void shutdownOutput() throws IOException {
98          // TODO what do we need to do here?
99          super.shutdownOutput();
100     }
101 }