背景:正在阅读《NIO与Socket编程技术指南》一书,在书中看到作者特别标注了 Server端和Client端ObjectInputStream 和 ObjectOutputStream 的创建顺序。我很疑惑,难道顺序有要求吗?找找看!
先简单测试一下
第一种情况,Server端和Client端都是生成ObjectInputStream 在前,ObjectOutputStream 在后。
Server端:
Client端:
结果:
这说明client已经连上了,但是都阻塞了。为什么阻塞最后再说!
第二种情况,Server端和Client端都是生成 ObjectOutputStream在前,ObjectInputStream在后。
图就算了!请尽情脑补!
结果:
Server端:
Client端:
Server端和Client端都收到了对方亲切的问候(数据)。
第三种情况,Sever端和Client端,ObjectInputStream的生成顺序相反。
比如:
Sever端:
ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
Client端:
ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
结果:
Server端:
Client端:
结果和第二种方式一致。双方进行了密切的交流(数据)。
OK,来点实际的!上面这一堆并没有说一个为什么,下面就来说说为什么
public ObjectInputStream(InputStream in) throws IOException {
verifySubclass();
bin = new BlockDataInputStream(in);
handles = new HandleTable(10);
vlist = new ValidationList();
serialFilter = ObjectInputFilter.Config.getSerialFilter();
enableOverride = false;
readStreamHeader(); // 这里,就是这里
bin.setBlockDataMode(true);
}
进入readStreamHeader方法瞅瞅
protected void readStreamHeader()
throws IOException, StreamCorruptedException
{
short s0 = bin.readShort(); // 注意这里
short s1 = bin.readShort(); // 还有这里
if (s0 != STREAM_MAGIC || s1 != STREAM_VERSION) { // 这里将获得的两个数据进行校验
throw new StreamCorruptedException(
String.format("invalid stream header: %04X%04X", s0, s1));
}
}
继续进入,其实不必进入了,在里面也是对数据的处理,这里就是一个读操作。
可以理解为创建一个ObjectInputStream 需要从对面读数据。如果两边都先创建ObjectInputStream的话,哪有数据写入,不堵才怪!
public ObjectOutputStream(OutputStream out) throws IOException {
verifySubclass();
bout = new BlockDataOutputStream(out);
handles = new HandleTable(10, (float) 3.00);
subs = new ReplaceTable(10, (float) 3.00);
enableOverride = false;
writeStreamHeader(); // 就是这里,写数据的那个地方
bout.setBlockDataMode(true);
if (extendedDebugInfo) {
debugInfoStack = new DebugTraceInfoStack();
} else {
debugInfoStack = null;
}
}
看看写了什么(两个数据,一个不差):
protected void writeStreamHeader() throws IOException {
bout.writeShort(STREAM_MAGIC); // Magic number that is written to the stream header.
bout.writeShort(STREAM_VERSION); // Version number that is written to the stream header.
}
简而言之,就是一个read等数据问题。write写了,自然没问题,没写,可不就得等着嘛(阻塞)。
最后,