所以,我正在尝试进行简单的Java套接字聊天。在进行任何聊天之前,只需要使用用户名进行简单登录。我发送"消息" (" Poruka"代码中)ObjectOutputStream上的对象," Message"对象包含" Sender,Receiver,Content,bool Login,bool Logout"。
序列是:
收到将用户添加到服务器端列表的信息后,服务器线程会向客户端发送相应的答案(问题就在这里)。
服务器线程代码:
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();
}
在这里,服务器线程可以很好地设置返回消息和适当的登录信息。如果登录成功,则将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冲突?还是仅仅是我的逻辑?没有线索。
答案 0 :(得分:1)
Java序列化旨在序列化对象图。如果一个对象出现多次,则只发送一次,并且两个引用都指向同一个对象。例如。您可以拥有两个对象A和B,其中每个对象都具有相互引用。但是使用引用并且只传递一次每个对象,这一切都有效
如果这不能按预期工作,那就是可变对象。如果多次传递一个对象,则会获得对同一对象的引用。它确实/无法检查您是否更改了它。
请注意,这意味着您保留所有写入或读取的对象,这可能是一个微妙的内存泄漏。
解决方案是调用reset()来清除缓存的对象并再次发送任何对象,包括更新。