黑马程序员技术交流社区

标题: 关于 ObjectOutputStream和ObjectInputStream在Socket中的运用 [打印本页]

作者: zuochbd    时间: 2014-10-2 18:06
标题: 关于 ObjectOutputStream和ObjectInputStream在Socket中的运用
本帖最后由 caixingke 于 2014-10-2 18:16 编辑

在TCP的socket编程中, 我喜欢用ObjectOutputStream和ObjectInputStream来进行数据传输.因为 这两个流类, 不仅具有普通InputStream和OutputStream的read和write方法,
而且, 还具有 DataInput和DataOutput接口, 可以对基本数据类型进行read和write, 可以用writeUTF和readUTF对字串对行read和write, 很方便.
而且, 其一个最大的特征是, 具有writeObject和readObject方法.
但在 socket编程中, 我发现了一个问题, 头痛了几天.
客户端程序经常在此处block掉:
ObjectInputStream = new ObjectInputStream(socket.getInputStream());

经过反复尝试, 发现出现block的情况是这样:
    客户端:
            ObjectInputStream reader = new ObjectInputStream(socket.getInputStream());
            ObjectOutputStream writer = new ObjectOutputStream(socket.getOutputStream());
    服务器端:
            ObjectInputStream reader = new ObjectInputStream(socket.getInputStream());
            ObjectOutputStream writer = new ObjectOutputStream(socket.getOutputStream());

即, 代码顺序如果这样的话, 就会在 客户端 :
         ObjectInputStream = new ObjectInputStream(socket.getInputStream());
这行代码处block掉.

而以其它顺序的话, 就没有这个问题.


经过反复debug, 得知其原因如下:
(话说, debug时, 发现myeclipse无法查看rt.jar包中的方法的局部变量的值, 郁闷. 如何查看rt.jar的局部变量值的问题 , 我还没解决.)
ObjectInputStream构造方法中:
    public ObjectInputStream(InputStream in) throws IOException {
        verifySubclass();
        bin = new BlockDataInputStream(in);
        handles = new HandleTable(10);
        vlist = new ValidationList();
        enableOverride = false;
        readStreamHeader();
        bin.setBlockDataMode(true);
    }


即, 里头有一个 readStreamHeader()方法.
客户端在构造ObjectInputStream对象时, 先接收一定的header数据,接收到这些数据之前会处于阻塞状态。即, 客户端和服务器端的ObjectInputStream都在等待对方的ObjectOutputStream发出来的header数据,
所以, 二者都没办法向下运行下去.









欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2