之前例子中已经介绍了如何使用socket进行信息的传输,及其如何进行多客户端的通信。
但是实际开发中,我们不可能只传输简单的基础类型的数据。更多的是要传输一个对象,或则信息包。
因此今天的场合要用到ObjectInputStream/ObjectOutputStream对象。
要传输对象,我们首先定义一个对象类User
1 public class User implements Serializable{ 2 3 4 /** 5 * java.io.InvalidClassException: com.lwx.bean.User; local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 8089718401965834129 6 7 */ 8 private static final long serialVersionUID = 8089718401965834129L; 9 public User() {10 11 }12 13 public User(int id, String name) {14 this.id = id;15 this.name = name;16 }17 18 private int id;19 private String name;20 public int getId() {21 return id;22 }23 24 public void setId(int id) {25 this.id = id;26 }27 28 public String getName() {29 return name;30 }31 32 public void setName(String name) {33 this.name = name;34 }35 36 }
注意的是,对象必须进行实例化。同时生成serialVersionUID。
接着我们创建服务端程序
服务端代码
1 /** 2 * @author draem0507@gmail.com 3 * @TODO java线程开发之三 对象传输 4 * @version 1.0 5 * @date 2013-5-7下午09:22:45 6 * @blgos myblog:http://www.cnblogs.com/draem0507 7 */ 8 9 public class ServerTest {10 private ServerSocket serverSocket;11 12 13 14 public ServerTest() {15 try {16 serverSocket = new ServerSocket(10000);17 // 开启无限循环 创建每个客户端的socket线程18 while (true) {19 Socket socket = serverSocket.accept();20 new ReceiveSocket(socket).start();21 }22 } catch (IOException e) {23 // TODO Auto-generated catch block24 e.printStackTrace();25 }26 27 }28 29 public static void main(String[] args) {30 new ServerTest();31 32 }33 34 private class ReceiveSocket extends Thread {35 private Socket socket;36 37 public ReceiveSocket(Socket socket) {38 this.socket = socket;39 }40 41 private ObjectInputStream reader;42 private ObjectOutputStream writer;43 44 @Override45 public void run() {46 47 try {48 reader=new ObjectInputStream(new BufferedInputStream(socket.getInputStream()));49 //writer=new ObjectOutputStream(socket.getOutputStream());50 // 开启无限循环 监控消息51 52 //java.io.EOFException53 Object obj= reader.readObject();54 if(obj!=null)55 {56 User user =(User)obj;57 System.out.println("id=="+user.getId()+"\tname=="+user.getName());58 }59 // while (true) {}60 61 } catch (IOException e) {62 // TODO Auto-generated catch block63 e.printStackTrace();64 } catch (ClassNotFoundException e) {65 // TODO Auto-generated catch block66 e.printStackTrace();67 } finally {68 if (null != reader) {69 try {70 reader.close();71 } catch (IOException e) {72 // TODO Auto-generated catch block73 e.printStackTrace();74 }75 }76 if (null != writer) {77 try {78 reader.close();79 } catch (IOException e) {80 // TODO Auto-generated catch block81 e.printStackTrace();82 }83 }84 try {85 socket.close();86 } catch (IOException e) {87 // TODO Auto-generated catch block88 e.printStackTrace();89 }90 }91 92 }93 94 }95 96 }
客户端代码
1 public class ClientTest { 2 3 4 public static void main(String[] args) throws Exception { 5 6 Socket socket = new Socket("localhost", 10000); 7 //ObjectInputStream in=new ObjectInputStream(socket.getInputStream()); 8 ObjectOutputStream out=new ObjectOutputStream(socket.getOutputStream()); 9 10 11 User user =new User();12 user.setId(1);13 user.setName("lwx_"+1);14 out.writeObject(user);15 out.flush();16 17 18 socket.close();19 20 21 }22 }
老规矩,先运行服务端,在执行客户端。这里跟之前相对,并没有实现服务端往客户端发送信息,要测试的朋友自己加代码,a piece of cake.
在看csdn的时候,看到有人写道关于压缩传输的介绍,就顺便把代码贴上来。
压缩服务端代码
1 //压缩对象的方式传输 2 public class MyServer { 3 4 private final static Logger logger = Logger.getLogger(MyServer.class.getName()); 5 6 public static void main(String[] args) throws IOException { 7 ServerSocket server = new ServerSocket(10000); 8 9 while (true) {10 Socket socket = server.accept();11 socket.setSoTimeout(10 * 1000);12 invoke(socket);13 }14 }15 16 private static void invoke(final Socket socket) throws IOException {17 new Thread(new Runnable() {18 public void run() {19 GZIPInputStream gzipis = null;20 ObjectInputStream ois = null;21 GZIPOutputStream gzipos = null;22 ObjectOutputStream oos = null;23 24 try {25 gzipis = new GZIPInputStream(socket.getInputStream());26 ois = new ObjectInputStream(gzipis);27 gzipos = new GZIPOutputStream(socket.getOutputStream());28 oos = new ObjectOutputStream(gzipos);29 30 Object obj = ois.readObject();31 User user = (User)obj;32 System.out.println("user: " + user.getId() + "/" + user.getName());33 34 user.setName(user.getName() + "_new");35 user.setId(user.getId() *2);36 37 oos.writeObject(user);38 oos.flush();39 gzipos.finish();40 } catch (IOException ex) {41 logger.log(Level.SEVERE, null, ex);42 } catch(ClassNotFoundException ex) {43 logger.log(Level.SEVERE, null, ex);44 } finally {45 try {46 ois.close();47 } catch(Exception ex) {}48 try {49 oos.close();50 } catch(Exception ex) {}51 try {52 socket.close();53 } catch(Exception ex) {}54 }55 }56 }).start();57 }58 }
压缩客户端代码
1 public class MyClient { 2 3 private final static Logger logger = Logger.getLogger(MyClient.class.getName()); 4 5 public static void main(String[] args) throws Exception { 6 for (int i = 0; i < 10; i++) { 7 Socket socket = null; 8 GZIPOutputStream gzipos = null; 9 ObjectOutputStream oos = null;10 GZIPInputStream gzipis = null;11 ObjectInputStream ois = null;12 13 try {14 socket = new Socket();15 SocketAddress socketAddress = new InetSocketAddress("localhost", 10000); 16 socket.connect(socketAddress, 10 * 1000);17 socket.setSoTimeout(10 * 1000);18 19 gzipos = new GZIPOutputStream(socket.getOutputStream());20 oos = new ObjectOutputStream(gzipos);21 User user = new User( i, "lwx_" + i);22 oos.writeObject(user);23 oos.flush();24 gzipos.finish();25 26 gzipis = new GZIPInputStream(socket.getInputStream());27 ois = new ObjectInputStream(gzipis);28 Object obj = ois.readObject();29 if (obj != null) {30 user = (User)obj;31 System.out.println("user: " + user.getId() + "/" + user.getName());32 }33 } catch(IOException ex) {34 logger.log(Level.SEVERE, null, ex);35 } finally {36 try {37 ois.close();38 } catch(Exception ex) {}39 try {40 oos.close();41 } catch(Exception ex) {}42 try {43 socket.close();44 } catch(Exception ex) {}45 }46 }47 }48 }