注意点一:待传输类以及类中所有属性要实现序列化接口,并且添加序列化版本号。
public class Person implements Serializable {
//添加一个静态常量:序列化版本号
private static final long serialVersionUID = -6844864770754661210L;
//这里Person类只有一个整型属性,其包装类Integer的父类Number已经实现了序列化接口
private int age;
public Person(int age) {
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
注意点二:在客户端和服务器端使用对象流传输对象则两端中待传输的类要一致
举一个例子:比如客户端用Android studio编写,服务器用IntelliJ IDEA编写。那么二者传输的类的包的声明、Import内容、以及类的内容要一样(除了代码注释以及变量的值可以不同)。当然,你在一个编译器上只用写一个类就行了。
注意点三:如果想在服务器端向客户端(反过来也是)不断传输不同内容的对象则每次都要新建一个这个对象写到流中,不然客户端接收到的一直是第一次传过来的值。
举例:待传输类为上边的Person类
服务器为:写了一个死循环不断向客户端写出对象p,p的属性年龄每次增加1。
@Test
public void server() {
int i = 1;
Person p = new Person(10);//待传输的对象
ServerSocket serverSocket = null;
Socket accept = null;
ObjectOutputStream objectOutputStream = null;
try {
serverSocket = new ServerSocket(1080);//指名服务器端口号
accept = serverSocket.accept();
objectOutputStream = new ObjectOutputStream(accept.getOutputStream());//对象输出流
while (true) {
p.setAge(i++);//改变对象中的值
System.out.println(p.getAge());//打印一下改变后的值
objectOutputStream.writeObject(p);
objectOutputStream.flush();
Thread.sleep(1000);//阻塞1秒
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
} finally {
if (accept != null) {
try {
accept.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (objectOutputStream != null) {
try {
objectOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
客户端为:
@Test
public void client() {
Socket socket = null;
ObjectInputStream oin = null;
try {
socket = new Socket("127.0.0.1", 1080);//连接的服务器为本机
oin = new ObjectInputStream(socket.getInputStream());
while (true) {
Object o = oin.readObject();//接收从服务器端读取来的对象
Person p = (Person) o;//强转为person类
System.out.println(p.getAge());//打印对象p中的年龄
}
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
} finally {
if (oin != null) {
try {
oin.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
按理说服务器和客户端打印结果都从1开始递增的数才对
实际结果为:
服务器正常但是客户端读取到的一直是第一次传过来的值
即服务器端每次都在一个对象上改然后将其传输到客户端,那么客户端从第二次开始都认为传过来的对象与第一次的对象相同。
正确做法是每次新建一个对象写出或者深拷贝一个对象出来去写出。
将上面服务器端改一下:
@Test
public void server() {
int i = 1;
ServerSocket serverSocket = null;
Socket accept = null;
ObjectOutputStream objectOutputStream = null;
try {
serverSocket = new ServerSocket(1080);//指名服务器端口号
accept = serverSocket.accept();
objectOutputStream = new ObjectOutputStream(accept.getOutputStream());//对象输出流
while (true) {
Person person = new Person(i++);
objectOutputStream.writeObject(person);//每次新建一个改变后的对象写出
objectOutputStream.flush();
System.out.println(person.getAge());//打印改变后的person
Thread.sleep(1000);//阻塞1秒
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
} finally {
if (accept != null) {
try {
accept.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (objectOutputStream != null) {
try {
objectOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
改完后结果为: