您的位置:首页 > 编程语言 > Java开发

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;
}

}
因为客户端和服务器的代码一样,所以就不发第二个了。

在学习编程的时候就是要遇到一个个问题,然后想办法解决,知识点就这样一点点的积累下来了,学习的深度和广度就上去了。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: