【问题标题】:new ObjectInputStream() blocks新的 ObjectInputStream() 块
【发布时间】:2013-01-01 13:45:29
【问题描述】:
public class SerProg {


    static ServerSocket ser=null;
    static Socket cli=null;
    static ObjectInputStream ins=null;
    static ObjectOutputStream outs=null;


    public static void main(String[] args) {

        try {

            ser=new ServerSocket(9000,10);
            cli=ser.accept();

            System.out.println("Connected to :"+cli.getInetAddress().getHostAddress()+" At Port :"+cli.getLocalPort());

            ins=new ObjectInputStream(cli.getInputStream());
            outs=new ObjectOutputStream(cli.getOutputStream());

            String str=(String)ins.readObject();


        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


    }

}

还有客户

public class SerProg {

    /**
     * @param args
     */
    static ServerSocket ser=null;
    static Socket cli=null;
    static ObjectInputStream ins=null;
    static ObjectOutputStream outs=null;


    public static void main(String[] args) {
        // TODO Auto-generated method stub

        try {

            ser=new ServerSocket(9000,10);
            cli=ser.accept();

            System.out.println("Connected to :"+cli.getInetAddress().getHostAddress()+" At Port :"+cli.getLocalPort());

            ins=new ObjectInputStream(cli.getInputStream());
            outs=new ObjectOutputStream(cli.getOutputStream());

            String str=(String)ins.readObject();


        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


    }

}

连接建立成功,但在服务器代码行中

ins=new ObjectInputStream(cli.getInputStream());

代码停止并且不继续,可能是什么问题??

【问题讨论】:

  • 你做了两次 SerProg 的代码

标签: java sockets objectinputstream


【解决方案1】:

您需要在连接两侧的ObjectInputStream 之前创建ObjectOutputStream(!)。创建ObjectInputStream 时,它会尝试从InputStream 中读取对象流标头。所以如果另一边的ObjectOutputStream还没有创建,还没有对象流头可以读取,它会无限期地阻塞。

或者换一种说法:如果双方首先构造ObjectInputStream,双方都会阻止尝试读取对象流标头,直到ObjectOutputStream被创建后才会被写入(在该行的另一边);这永远不会发生,因为双方都被 ObjectInputStream 的构造函数阻塞了。

这可以从ObjectInputStream(InputStream in)的Javadoc推断:

从流中读取序列化流标头并进行验证。此构造函数将阻塞,直到相应的 ObjectOutputStream 已写入并刷新标头。

这也在 Esmond Pitt 的 Java 中的基本网络 的第 3.6.2 节中进行了描述。

【讨论】:

  • 我不明白为什么 ObjectOutputStream 和 ObjectInputStream 之间的顺序是相关的
  • @benjarobin 如果双方首先构造ObjectInputStream,则双方都会阻止尝试读取对象流标头,直到创建ObjectOutputStream(在另一边该行的);这永远不会发生,因为双方都被 ObjectInputStream 的构造函数阻塞。
  • 对不起误会你的留言了,对不起!!!您的评论很清楚,您应该将其添加到您的答案中。我不明白客户端和服务器都在双向发送对象(我的错)你从我那里获得 +1 :-)
  • 我看到很多重复的问题,答案都是一样的,不幸的是这个解决方案对我不起作用,你有什么其他建议吗?
  • @danibilel 在某些实现中,可能需要在创建ObjectOutputStream 之后创建ObjectInputStream 之后立即显式调用flush()。但是,在所有情况下,您都必须在两边构造 out 之前,以防止相互等待。
【解决方案2】:

您必须为流进行握手。我的意思是在客户端,当你创建一个对象输入流时,你必须在服务器端创建一个对象输出流。

//SERVER SIDE
Socket clientSocket = TcpServer.socket.accept();
// 1. input stream;
ObjectInputStream sInput = new ObjectInputStream(clientSocket.getInputStream());
// 2. output stream
ObjectOutputStream sOutput = new ObjectOutputStream(clientSocket.getOutputStream());


//CLIENT SIDE
Socket socket = new Socket(ip, port);
// 2. output stream
ObjectOutputStream sOutput = new (socket.getOutputStream());
// 1. input stream
ObjectInputStream sInput = new ObjectInputStream(socket.getInputStream());

我试图展示如何为流进行握手。

【讨论】:

  • 不一定是客户端首先创建ObjectOutputStream:它可以是任一端,但最安全的是先在both端创建它.那么你就没有问题了。
猜你喜欢
  • 2011-08-05
  • 1970-01-01
  • 1970-01-01
  • 2020-05-24
  • 1970-01-01
  • 1970-01-01
  • 2020-05-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多