java对象传输流C/S传输对象
2016-04-11 17:58
423 查看
java对象传输流C/S传输对象
java中有一个对象输入输出流,它可以包装普通的字节流。我用一个C/S模式来测试练习对象输入输出流。
创建对象输入输出流包装基本字节流时遇到了第一个问题:
服务器创建输出流后,客户端一定也要先创建输入流,跟服务器相对应,与服务器输出流连接起来。相应的,服务器的输入流也要跟客户端的输出流对应。不可以同时创建输出流,不然的话两边都会进入等待状态,造成死锁。
遇到第二个问题:
创建的文件信息对象没有序列化。弹出的异常如下:
NotSerializableException异常。后来我的文件信息对象实现了序列化接口这个异常就没有了。
但是第三个问题又出现了:
客户端连接中断,原因是:我的程序是作为测试用的,所以没有那么多的线程死循环之类结构,所以服务器对象就先运行完,关闭了,而客户端对象还没有接受读取对象流呢。
接下来我在服务器端加入了休眠代码,然后这个问题也解决了。
几番捣鼓终于出现让人欣喜的输出:
这时我就想,SVN的服务器信息列表应该是多次添加文件,更新文件列表的,于是我就尝试继续添加文件信息对象进入map然后通过对象流传入客户端。
但就在这时出现了第四个问题了:
我重新添加了键值对进入服务器的HashMap中,客户端也多次读取,可是结果依然跟上次运行结果一样。
左哥说这是map内部运行机制的原因,叫我们不用深究。
我就没有继续研究下去,然后解决的方法就是重新创建一个map1对象然后用putAll()方法,把map里面的东西全部放到map1中,还有新的文件信息。
然后把新的信息传输给客户端就可以。
测试结果如下图:
把服务器,客户端测试的代码发上来:
这是服务器的:
package control; import java.io.InputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; import java.util.HashMap; import dao.FileInfomationDao; public class MyServer { public static HashMap<String,FileInfomationDao> map = new HashMap<String,FileInfomationDao>(); { for(int i=0;i<5;i++){ String fileName = "文件"+i; FileInfomationDao fifd = new FileInfomationDao(fileName, 10000, "C://", "LongSX"); map.put(fileName, fifd); } } public static void main(String[] args) { MyServer ms = new MyServer(); ms.initMyServer(); } public void initMyServer(){//服务器程序 try { ServerSocket ss = new ServerSocket(9090); Socket socket = ss.accept(); System.out.println("连接客户端成功..."); InputStream ins = socket.getInputStream(); OutputStream ous = socket.getOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(ous); oos.writeObject(map); oos.flush(); String fileName = "LongSX(add)"; FileInfomationDao fifd = new FileInfomationDao(fileName,1000,"C://","LongSX"); HashMap<String,FileInfomationDao> map1 = new HashMap<String,FileInfomationDao>(); map1.putAll(map); map1.put(fileName, fifd); oos.writeObject(map1); oos.flush(); Thread.sleep(2000); System.out.println("文件发送完毕"); } catch (Exception e) { e.printStackTrace(); } } }
下面是客户端的:
package control; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.net.Socket; import java.util.HashMap; import java.util.Iterator; import java.util.Set; import dao.FileInfomationDao; public class MyClient { public static void main(String[] args) { MyClient mc = new MyClient(); mc.initMyClient(); } public void initMyClient(){ try { Socket socket = new Socket("localhost",9090); System.out.println("连接服务器成功..."); InputStream ins = socket.getInputStream(); OutputStream ous = socket.getOutputStream(); ObjectInputStream ois = new ObjectInputStream(ins); HashMap<String,FileInfomationDao> map = (HashMap<String, FileInfomationDao>) ois.readObject(); map = (HashMap<String, FileInfomationDao>) ois.readObject(); Set<String> set = map.keySet(); Iterator<String> ite = set.iterator(); while(ite.hasNext()){ FileInfomationDao fifd = map.get(ite.next()); System.out.println(fifd.getFileName()+" "+fifd.getOwnerName()); } System.out.println("对象接收完毕"); } catch (Exception e) { e.printStackTrace(); } } }
最后一个就是文件信息类,这个类客户端和服务器都有一个,服务器就是传输这个对象给客户端,所以要在这个类实现序列化接口。
代码如下:
package dao; import java.io.Serializable; public class FileInfomationDao implements Serializable{//服务器的文件信息数据对象 private String fileName; private long size; private String path; private String ownerName; public FileInfomationDao(String fileName, long size, String path, String ownerName) { super(); this.fileName = fileName; this.size = size; this.path = path; this.ownerName = ownerName; } public String getFileName() { return fileName; } public void setFileName(String fileName) { this.fileName = fileName; } public long getSize() { return size; } public void setSize(long size) { this.size = size; } public String getPath() { return path; } public void setPath(String path) { this.path = path; } public String getOwnerName() { return ownerName; } public void setOwnerName(String ownerName) { this.ownerName = ownerName; } }因为客户端和服务器的代码一样,所以就不发第二个了。
在学习编程的时候就是要遇到一个个问题,然后想办法解决,知识点就这样一点点的积累下来了,学习的深度和广度就上去了。
相关文章推荐
- Java 正则表达式 量词 --- 三种匹配模式【贪婪型、勉强型、占有型】
- 如何在高并发环境下设计出无锁的数据库操作(Java版本) 转载
- Java中HashMap,LinkedHashMap,TreeMap的区别
- Java多线程编程(一)
- 模拟器调试真机,没有在Android Studio 或者Eclipse 中发现真机
- Spring4 MVC入门教程
- java中四种引用类型
- java.lang.ClassNotFoundException: com.demo.search.extractAbstract.service.ExtractAbstractServiceHandler
- Java synchronized详解
- 使用java技术将Excel表格内容导入mysql数据库
- Java匿名内部类怎样创建,有何作用和优点,创建线程怎样使用匿名内部类
- LeetCode 338 -Counting Bits ( JAVA )
- java中为什么要引入匿名类?
- JAVA中局部内部类和匿名内部类的特点和作用?最好能详细说明
- [Java] 02 String的常用方法
- Java多线程学习(吐血超详细总结)
- JAVA MYSQL 插入数据后获取自增ID
- java的反射机制浅谈
- Java——数组、向量(Vector)详解
- Dubbo中对Spring配置标签扩展