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

时间:2016-09-03 17:32:31

标签: java sockets chat objectinputstream java-threads

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

序列是:

  1. 客户端发送Message(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();
    }
    
  4. 在这里,服务器线程可以很好地设置返回消息和适当的登录信息。如果登录成功,则将Message.Content设置为" ACCEPTED",否则将其设置为" DENIED"。我仔细检查了一下。

    现在,问题是:客户端始终接收带有" ACCEPTED"的消息对象。出于某种原因?

    这是客户端线程代码:

      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冲突?还是仅仅是我的逻辑?没有线索。

1 个答案:

答案 0 :(得分:1)

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

如果这不能按预期工作,那就是可变对象。如果多次传递一个对象,则会获得对同一对象的引用。它确实/无法检查您是否更改了它。

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

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