java中socket同时传递不同类型流的问题

服务器端accept()后就向客户端发送msg字符串和list字符串数组
PrintWriter out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream(), "UTF-8"), true);
out.println(msg);

ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
out.writeObject(list);
out.flush();
客户端开两个子线程(用死循环)分别接收
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream(),"UTF-8"));
read = in.readLine();

ObjectInputStream oi = new ObjectInputStream(socket.getInputStream());
String[] str = (String[]) (oi.readObject());
现在问题是BufferedReader总是把对象流发过来的数据收了,怎么解决?
最新回答
东城冷人

2020-06-08 20:59:25

不是很明白你为什么这么做,一般是只会封装一个输入流,不会分开两个来获取数据的。
流底层都是二进制数据流,无论你用什么流去读都是读同样的数据,声明两个输出流输出后,对于客户端还是只能看到一个流输入,不会给你分开的。所以这里你开两个子进程读,就会出现谁运行快就把数据读出来了,而且看你PrintWriter也没有flush,所以应该只传输了list数据,客户端BufferedReader先运行,就把数据读出来了。
正确的做法是你先要决定服务器与客户端的数据交换方式,到底是基于二进制、指定编码的字符还是对象?看你上面的情况,你想传输一个list,二进制和指定编码字符都比较麻烦,你需要把list通过某种转换成二进制或者是字符(通常是转成XML)。比较简单的就是像你上面那样传输对象,msg是个String对象,本身就可以用ObjectOutputStream传输,没有必要再用一个PrintWriter传输。
追问
PrintWriter没有flush是我在第二个参数写了true,自动的。

如果msg用对象流传的话,文字编码问题会出问题吗?msg里面有中英文
追答
设置autoflush后流的行为是依赖具体实现类的,不一定就是write之后flush,你也没有把PrintWriter关掉,所以应该是没写过去。一般都是要显式调用flush的。
对象流传输的对象是用Java内部的编码的,这个你不用担心,不会乱码的。倒是使用PrintWriter有可能会乱码,因为客户端使用BufferedReader是使用系统默认编码读取二进制数据的。
追问
刚刚用对象流试了一下。
inputLine = (String) in.readObject(); //in为ObjectInputStream
这一句报错java.io.StreamCorruptedException: invalid type code: AC
追答
网络传输用BufferedInputStream和BufferedOutputStream封装一下
ObjectOutputStream out = new ObjectOutputStream(new BufferedInputStream(socket.getOutputStream()));

ObjectInputStream oi = new ObjectInputStream(new BufferedOutputStream(socket.getInputStream()));
素婉纤尘

2022-10-29 12:47:22

接收方得认识。。。。接收方才不会帮你区分是什么类型的流,谁先读就是谁读到。

要自己写一个协议这样的做法
发送包类别
长度