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"。
顺序是:
- 客户端发送消息 (Poruka),登录设置为 true,发件人设置为用户名(工作正常)
- 服务器线程成功接收到消息,如果列表中不存在相似的用户名,则将新用户添加到列表中(工作正常)
服务器端收到添加用户到列表的信息后,服务器线程向客户端发送适当的应答(问题来了)。
服务器线程代码:
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() 清除缓存的对象并再次发送任何对象,包括更新。
所以,我正在尝试进行简单的 java 套接字聊天。在可以进行任何聊天之前,只需要使用用户名进行简单登录。我通过 ObjectOutputStream 发送 "Message"(代码中的 "Poruka")对象,"Message" 个对象包含 "Sender, Receiver, Content, bool Login, bool Logout"。
顺序是:
- 客户端发送消息 (Poruka),登录设置为 true,发件人设置为用户名(工作正常)
- 服务器线程成功接收到消息,如果列表中不存在相似的用户名,则将新用户添加到列表中(工作正常)
服务器端收到添加用户到列表的信息后,服务器线程向客户端发送适当的应答(问题来了)。
服务器线程代码:
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() 清除缓存的对象并再次发送任何对象,包括更新。