Java 套接字聊天应用程序 - 客户端 ObjectInputStream gets/reads 错误的响应对象

Java socket chat application - client ObjectInputStream gets/reads wrong response Object

所以,我正在尝试进行简单的 java 套接字聊天。在可以进行任何聊天之前,只需要使用用户名进行简单登录。我通过 ObjectOutputStream 发送 "Message"(代码中的 "Poruka")对象,"Message" 个对象包含 "Sender, Receiver, Content, bool Login, bool Logout"。

顺序是:

  1. 客户端发送消息 (Poruka),登录设置为 true,发件人设置为用户名(工作正常)
  2. 服务器线程成功接收到消息,如果列表中不存在相似的用户名,则将新用户添加到列表中(工作正常)
  3. 服务器端收到添加用户到列表的信息后,服务器线程向客户端发送适当的应答(问题来了)。

    服务器线程代码:

       try {
    
        Poruka poruka = null;
        Poruka odgovor = new Poruka();
        while (true) {
            poruka = (Poruka) in.readObject();
             System.out.println("salje prije ifLogin "+poruka.getSalje()+" "+ poruka.isLogin());
            if (poruka.isLogin()) {
                System.out.println("salje "+poruka.getSalje());
                boolean success = Server.dodajKorisnika(poruka.getSalje());
    
                System.out.println("Uspjeh? "+success);
                //System.out.println("Jeste LOGIN poruka "+odgovor.getSadrzaj()+" "+odgovor.isLogout());
                if (success) {
                    System.out.println("USLO  U TRUE BLOK");
                    odgovor.setSadrzaj("ACCEPTED");
                    out.writeObject(odgovor);
               //     out.flush();
                }
                else{
                 odgovor.setSadrzaj("DENIED");
                    out.writeObject(odgovor);
                   // out.flush();
                    System.out.println(odgovor.getSadrzaj()+ " IZ BLOKA NEUSPJEH");
                }
            }
            System.out.println("PORUKA " + poruka.isLogin() + " " + poruka.getSalje());
        }
    } catch (Exception ex) {
        ex.printStackTrace();
    }
    

在这里,服务器线程在设置 return 具有适当登录信息的消息方面做得很好。如果登录成功,Message.Content设置为"ACCEPTED",否则设置为"DENIED"。我仔细检查了一下。

现在,问题是:客户端 总是 出于某种原因接收带有 "ACCEPTED" 的 Message 对象?

这是客户端线程代码:

  public boolean prijaviSe(String ime) {
    boolean ret = false;
    Poruka prijava = new Poruka();
    prijava.setSalje(ime);
    prijava.setLogin(true);

    try {
        System.out.println("PRIJAVA " + prijava.getSalje());
        out.writeObject(prijava);
        out.flush();
        while (true) {
            Poruka odgovor = (Poruka) in.readObject();
            System.out.println("ODGOVOR "+odgovor.getSadrzaj());
            if (odgovor.getSadrzaj().equals("ACCEPTED")) {
                prijavljen = true;
                  System.out.println("accepted");
                gui.setLabelaPrijavljen("Korisnik uspješno prijavljen");
                break;
            } else if (odgovor.getSadrzaj().equals("DENIED")) {
                prijavljen = false;
                 System.out.println("denied");
                  gui.setLabelaPrijavljen("Promijenite korisničko ime!");
            }
        }//while

    } catch (Exception ex) {
        ex.printStackTrace();
    }
    return ret;
}

我什至不确定要在这里寻找什么?是线程问题吗?某种 OutputStream / InputStream 冲突?或者这只是我的逻辑?一点头绪都没有。

Java 序列化旨在序列化对象图。如果一个对象出现不止一次,它只被发送一次,并且两个引用都指向同一个对象。例如。您可以有两个对象 A 和 B,其中每个对象都相互引用。但是使用引用并且只传递每个对象一次,这一切都有效

这不能按预期工作的地方是可变对象。如果您多次传递一个对象,您将获得对同一对象的引用。它 does/can 不会检查您是否更改了它。

请注意,这意味着您将保留曾经写入或读取的每个对象,这可能是一个微妙的内存泄漏。

解决方案是调用 reset() 清除缓存的对象并再次发送任何对象,包括更新。