java 传递对象_JAVA TCP传递对象的基本实现

Java的对象序列化是指将那些实现了Serializable接口的对象转换成一个字符序列,并能够在以后将这个字节序列完全恢复为原来的对象。这一过程甚至可通过网络进行,这意味着序列化机制能自动弥补不同操作系统之间的差异。 只要对象实现了Serializable接口(记住,这个接口只是一个标记接口,不包含任何的方法如果我们想要序列化一个对象,首先要创建某些OutputStream(如FileOutputStream、ByteArrayOutputStream等),然后将这些OutputStream封装在一个ObjectOutputStream中。这时候,只需要调用writeObject()方法就可以将对象序列化,并将其发送给OutputStream(记住:对象的序列化是基于字节的,不能使用Reader和Writer等基于字符的层次结构)。而反序列的过程(即将一个序列还原成为一个对象),需要将一个InputStream(如FileInputstream、ByteArrayInputStream等)封装在ObjectInputStream内,然后调用readObject()即可。对象序列化过程不仅仅保存单个对象,还能追踪对象内所包含的所有引用,并保存那些对象(这些对象也需实现了Serializable接口)。

要传递对象的引用属性类:

package yh.tcp.server;

import java.io.Serializable;

public class CoordObject implements Serializable{

private static final long serialVersionUID = 1L;

private double x;

private double y;

public double getX() {

return x;

}

public void setX(double x) {

this.x = x;

}

public double getY() {

return y;

}

public void setY(double y) {

this.y = y;

}

public CoordObject(double x, double y) {

super();

this.x = x;

this.y = y;

}

@Override

public String toString() {

return "CoordObject [x=" + x + ", y=" + y + "]";

}

}

要传递的对象类型:

package yh.tcp.server;

import java.io.Serializable;

public class PersonObject implements Serializable{

private static final long serialVersionUID = 1L;

private String name;

private int age;

private CoordObject coord;

public PersonObject(String name, int age, CoordObject coord) {

super();

this.name = name;

this.age = age;

this.coord = coord;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

public CoordObject getCoord() {

return coord;

}

public void setCoord(CoordObject coord) {

this.coord = coord;

}

@Override

public String toString() {

return "PersonObject [name=" + name + ", age=" + age + ", coord="

+ coord + "]";

}

}

服务端:

package yh.tcp.server;

import java.io.IOException;

import java.io.InputStream;

import java.io.ObjectInputStream;

import java.io.ObjectOutput;

import java.io.ObjectOutputStream;

import java.io.OutputStream;

import java.net.ServerSocket;

import java.net.Socket;

public class TCPServer {

public static void main(String[] args) throws IOException {

ServerSocket server = null;

Socket client = null;

ObjectOutputStream oos = null;

ObjectInputStream ois = null;

server = new ServerSocket(8888);

System.out.println("服务器开启,等待客户端访问……");

client = server.accept();

CoordObject coord=new CoordObject(1.1, 2.2);

PersonObject person=new PersonObject("name", 123, coord);

oos=new ObjectOutputStream(client.getOutputStream());

oos.writeObject(person);

oos.close();

client.close();

}

}

客户端:

package yh.tcp.client;

import java.io.IOException;

import java.io.ObjectInputStream;

import java.net.Socket;

import java.net.UnknownHostException;

public class TCPClient {

public static void main(String[] args) throws UnknownHostException, IOException, ClassNotFoundException {

Socket client = null;

ObjectInputStream ois=null;

client =new Socket("localhost",8888);

ois=new ObjectInputStream(client.getInputStream());

Object object=ois.readObject();

System.out.println(object);

ois.close();

client.close();

}

}

打印结果:

PersonObject [name=name, age=age, coord=CoordObject [x=1.1, y=2.2]]

以上不具备多次交互,且不支持多线程为多个客户端提供链接的机制。

下面的实例,可以让客户端对服务端序列化的对象进行操作,并且支持多个客户端同时访问。

增加线程类:

package yh.tcp.server;

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.ObjectOutputStream;

import java.net.Socket;

public class TcpThread implements Runnable {

private Socket client;

public Socket getClient() {

return client;

}

public void setClient(Socket client) {

this.client = client;

}

public TcpThread(Socket client) {

super();

this.client = client;

}

@Override

public void run() {

BufferedReader buf = null;

ObjectOutputStream oos = null;

try {

oos = new ObjectOutputStream(client.getOutputStream());

buf=new BufferedReader(new InputStreamReader(client.getInputStream()));

boolean flag=true;

while (flag) {

String str=buf.readLine();

if(str==null||"".equals(str)||"bye".equals(str)){

flag=false;

}else {

CoordObject coord=new CoordObject(121.1, 43.1);

PersonObject person=new PersonObject(str, 100, coord);

oos.writeObject(person);

}

}

System.out.println("当前断开一位~");

oos.close();

client.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

修改服务端:

package yh.tcp.server;

import java.io.IOException;

import java.net.ServerSocket;

import java.net.Socket;

public class TCPServer {

public static void main(String[] args) throws IOException {

ServerSocket server = null;

Socket client = null;

server = new ServerSocket(8888);

boolean flag = true;

while (flag) {

System.out.println("服务器开启,等待客户端访问……");

client = server.accept();

new Thread(new TcpThread(client)).start();

}

server.close();

}

}

修改客户端:

package yh.tcp.client;

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.ObjectInputStream;

import java.io.PrintStream;

import java.net.Socket;

import java.net.UnknownHostException;

public class TCPClient {

public static void main(String[] args) throws UnknownHostException, IOException, ClassNotFoundException {

Socket client = null;

ObjectInputStream ois=null;

PrintStream out=null;

BufferedReader writeInput=null;

client =new Socket("localhost",8888);

writeInput=new BufferedReader(new InputStreamReader(System.in));//键盘打印流

out=new PrintStream(client.getOutputStream());//向服务端输出流

ois=new ObjectInputStream(client.getInputStream());//从服务端接受的输入流

boolean flag=true;

while (flag) {

System.out.println("请输入信息~");

String str=writeInput.readLine();

out.println(str);

if ("".equals(str)||null==str||"bye".equals(str)) {

flag=false;

}else {

Object object=ois.readObject();

System.out.println(object);

}

}

ois.close();

client.close();

out.close();

}

}

打印结果:对于汉字的序列化反序列化也没出现乱码

9796b9b47c469099a2844d365faad739.png

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值