Java Socket实战之四:传输压缩对象
上一篇文章说到了用Java Socket来传输对象,但是在有些情况下比如网络环境不好或者对象比较大的情况下需要把数据对象进行压缩然后在传输,此时就需要压缩这些对象流,此时就可以GZIPInputStream和GZIPOutputStream来处理一下socket的InputStream和OutputStream。
仍然需要一个实现了java.io.Serializable接口的简单Java对象:
- packagecom.googlecode.garbagecan.test.socket.sample4;
- publicclassUserimplementsjava.io.Serializable{
- privatestaticfinallongserialVersionUID=1L;
- privateStringname;
- privateStringpassword;
- publicUser(){
- }
- publicUser(Stringname,Stringpassword){
- this.name=name;
- this.password=password;
- }
- publicStringgetName(){
- returnname;
- }
- publicvoidsetName(Stringname){
- this.name=name;
- }
- publicStringgetPassword(){
- returnpassword;
- }
- publicvoidsetPassword(Stringpassword){
- this.password=password;
- }
- }
在Server端使用,socket的InputStream首先被包装成GZIPInputStream,然后又被包装成ObjectInputStream,而socket的OutputStream首先被包装成GZIPOutputStream,然后又被包装成ObjectOutputStream,如下:
- packagecom.googlecode.garbagecan.test.socket.sample4;
- importjava.io.IOException;
- importjava.io.ObjectInputStream;
- importjava.io.ObjectOutputStream;
- importjava.net.ServerSocket;
- importjava.net.Socket;
- importjava.util.logging.Level;
- importjava.util.logging.Logger;
- importjava.util.zip.GZIPInputStream;
- importjava.util.zip.GZIPOutputStream;
- publicclassMyServer{
- privatefinalstaticLoggerlogger=Logger.getLogger(MyServer.class.getName());
- publicstaticvoidmain(String[]args)throwsIOException{
- ServerSocketserver=newServerSocket(10000);
- while(true){
- Socketsocket=server.accept();
- socket.setSoTimeout(10*1000);
- invoke(socket);
- }
- }
- privatestaticvoidinvoke(finalSocketsocket)throwsIOException{
- newThread(newRunnable(){
- publicvoidrun(){
- GZIPInputStreamgzipis=null;
- ObjectInputStreamois=null;
- GZIPOutputStreamgzipos=null;
- ObjectOutputStreamoos=null;
- try{
- gzipis=newGZIPInputStream(socket.getInputStream());
- ois=newObjectInputStream(gzipis);
- gzipos=newGZIPOutputStream(socket.getOutputStream());
- oos=newObjectOutputStream(gzipos);
- Objectobj=ois.readObject();
- Useruser=(User)obj;
- System.out.println("user:"+user.getName()+"/"+user.getPassword());
- user.setName(user.getName()+"_new");
- user.setPassword(user.getPassword()+"_new");
- oos.writeObject(user);
- oos.flush();
- gzipos.finish();
- }catch(IOExceptionex){
- logger.log(Level.SEVERE,null,ex);
- }catch(ClassNotFoundExceptionex){
- logger.log(Level.SEVERE,null,ex);
- }finally{
- try{
- ois.close();
- }catch(Exceptionex){}
- try{
- oos.close();
- }catch(Exceptionex){}
- try{
- socket.close();
- }catch(Exceptionex){}
- }
- }
- }).start();
- }
- }
Client也和Server端类似,同样要不socket的XXXStream包装成GZIPXXXStream,然后再包装成ObjectXXXStream,如下:
- packagecom.googlecode.garbagecan.test.socket.sample4;
- importjava.io.IOException;
- importjava.io.ObjectInputStream;
- importjava.io.ObjectOutputStream;
- importjava.net.InetSocketAddress;
- importjava.net.Socket;
- importjava.net.SocketAddress;
- importjava.util.logging.Level;
- importjava.util.logging.Logger;
- importjava.util.zip.GZIPInputStream;
- importjava.util.zip.GZIPOutputStream;
- publicclassMyClient{
- privatefinalstaticLoggerlogger=Logger.getLogger(MyClient.class.getName());
- publicstaticvoidmain(String[]args)throwsException{
- for(inti=0;i<10;i++){
- Socketsocket=null;
- GZIPOutputStreamgzipos=null;
- ObjectOutputStreamoos=null;
- GZIPInputStreamgzipis=null;
- ObjectInputStreamois=null;
- try{
- socket=newSocket();
- SocketAddresssocketAddress=newInetSocketAddress("localhost",10000);
- socket.connect(socketAddress,10*1000);
- socket.setSoTimeout(10*1000);
- gzipos=newGZIPOutputStream(socket.getOutputStream());
- oos=newObjectOutputStream(gzipos);
- Useruser=newUser("user_"+i,"password_"+i);
- oos.writeObject(user);
- oos.flush();
- gzipos.finish();
- gzipis=newGZIPInputStream(socket.getInputStream());
- ois=newObjectInputStream(gzipis);
- Objectobj=ois.readObject();
- if(obj!=null){
- user=(User)obj;
- System.out.println("user:"+user.getName()+"/"+user.getPassword());
- }
- }catch(IOExceptionex){
- logger.log(Level.SEVERE,null,ex);
- }
- try{
- oos.close();
- }catch(IOExceptione){
- }
- try{
- ois.close();
- }catch(IOExceptione){
- }
- try{
- socket.close();
- }catch(IOExceptione){
- }
- }
- }
- }
最后测试上面的代码,首先运行Server类,然后运行Client类,就可以分别在Server端和Client端控制台看到接收到的User对象实例了。
原文链接:http://blog.youkuaiyun.com/kongxx/article/details/7259834