【问题标题】:My program gets stuck/block in "in.readObject()" even with flush()即使使用flush(),我的程序也会卡在“in.readObject()”中
【发布时间】:2016-03-19 10:45:13
【问题描述】:

我正在尝试使用带有多线程客户端和服务器的 Java 实现聊天(因为服务器正在运行 2 个线程/客户端,1 个用于接收,1 个用于发送),现在我遇到了一个问题客户端在执行in.readObject(); 时卡住了。 我已经搜索过,大多数答案是由于缺少flush() 因为in 会阻塞,但是我已经在发送消息的任何地方插入了flush(),即使在初始化流之后也是如此。我知道我正在发送一条消息,但是客户端似乎没有收到它。 客户端仅使用 1 个线程来接收和发送。 客户端当前卡在下面一行的run() 方法中。

obj = in.readObject();

这是客户端代码。 (对不起混合语言)

public Cliente(JTextArea panel, String Utilizador, String destinatario,String title){
    super();
    this.panel = panel;
    this.Utilizador = Utilizador;
    this.destinatario = destinatario;
    this.title = title;

    try {
        cliente = new Socket(host,porto);
        out = new ObjectOutputStream(cliente.getOutputStream());
        out.flush();
        in = new ObjectInputStream(cliente.getInputStream());

    } catch (Exception e) {
        e.printStackTrace();
    }

}


public void run() {
    System.out.println("Inside RUN! (Receiving) - Cliente");

        System.out.println("in variable declared - Cliente");
        //escuta as mensagens do servidor e mostra no painel
        while(true){
            Object obj;
            try{
            //----------------------------------------------
            System.out.println("Last sentence. RIP");
            obj = in.readObject(); // MUDAR MUDAR MUDAR MUDAR MUDAR MUDAR MUDAR  MUDAR MUDAR  MUDAR MUDAR  MUDAR MUDAR
            System.out.println("Recebido um objecto - Cliente");
            if(obj instanceof Message){
                String mensagem;
                mensagem = ((Message) obj).getMessage();
                mensagem += "\n";
                panel.append(mensagem+"\n");
                GuardarConversa();
            }       
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

//envia mensagens ao servidor
public void enviarMsg(Message msg){
    try {
        System.out.println("A Enviar msg! - Client.java");
        out.writeObject(msg);
        out.flush();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

这里是服务器类,只是发送者。似乎正在发送消息。

private void EnviarMensagem(){

    //EnviarListaContactos();

    while(true){
            Message msg;
            if(MessageQueue.getMessage().getDestiny().equals(MyName)){

                System.out.println("Encontrada uma mensagem na fila - EnviarDados");

                msg = MessageQueue.getMessage();
                try {
                    System.out.println("A enviar mensagem para o cliente - Enviar Dados");
                    out.writeObject(msg);
                    out.flush();
                    System.out.println("Mensagem enviada - Enviar Dados");
                    System.out.println("Out="+out);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                MessageQueue.removeMessage(msg);                    
            }
        }
}

我知道这是一个常见的问题,但常见的解决方案似乎没有做到这一点。

【问题讨论】:

    标签: java multithreading sockets flush


    【解决方案1】:

    readObject() 将在没有对象或流结尾或异常可用时阻塞。你有一个无限循环,它应该在EOFException 或除SocketTimeoutException 之外的任何IOException 上终止,但它不会,所以它当然会阻塞,除非对等点是瞬时对象的无穷来源.

    【讨论】:

    • 是的,没错,但我正在发送消息。我将它插入聊天区域,所有print 都表明它正在通过,因为所有发送部分都已完全完成。它不应该检测到正在发送的Object 并处理它吗?
    • 那么肯定是有异常,或者这两个socket没有互相连接。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多