我正在用自己的客户端-服务器体系结构开发Java多人游戏。简而言之,客户端每秒请求服务器的World对象的副本30次,并且在接收到该副本之后,将其客户端副本设置为响应。这一切都使用Java的标准net API完成。
我遇到的问题是,我还在世界上存储了一个Player对象的ArrayList,并且当我将Player添加到此列表中时,客户端无法获取更新。它仍然从服务器接收世界的副本,但是不是最新的。
在过去的项目中,我遇到了类似的问题,该问题是由write / readObject引起的,并通过使用write / readUnshared进行了修复,但即使这样也不起作用。
以下是通信服务器端的重要内容:
String message;
int sum = 0;
while(active)
{
message = "";
try {
message = in.readUTF();
} catch (IOException e) {
active = false;
System.out.println("Lost connection with client " + socket.getInetAddress());
}
if(message.equals("GETWORLD"))
{
try {
sum++;
if(sum == 100)
main.world.addPlayer(999, 2, 2);
System.out.println("Client requested world (#" + sum + ")");
System.out.println(main.world.players.size());
out.writeUnshared(main.world);
out.flush();
System.out.println("Sent client world (#" + sum + ")");
} catch (IOException e) {
active = false;
System.out.println("Lost connection with client " + socket.getInetAddress());
}
}
if(message.equals("DISCONNECT"))
{
active = false;
System.out.println("Client " + socket.getInetAddress() + " requested disconnect");
}
}
然后是客户端:
Object read = null;
int sum = 0;
while(active)
{
try {
Thread.sleep((long)(1000 / 30.0));
if(connected)
{
sum++;
System.out.println("Asking server for world (#" + sum + ")");
out.writeUTF("GETWORLD");
out.flush();
read = in.readUnshared();
if(read instanceof World)
{
World temp = (World)read;
System.out.println(temp.players.size());
frame.panel.updateWorld((World)read);
System.out.println("Got world from server (#" + sum + ")");
}
}
} catch (InterruptedException | ClassNotFoundException e1) {
active = false;
e1.printStackTrace();
} catch (IOException e2) {
active = false;
System.out.println("Lost connection with server @ " + socket.getInetAddress());
frame.dispose();
System.exit(0);
}
}
显然,sum变量用于调试。 我用一些输出进一步测试了这一点,这是令我恐惧的地方:
Client log:
...
Asking server for world (#99)
1
Got world from server (#99)
Asking server for world (#100)
1
Got world from server (#100)
Asking server for world (#101)
1
Got world from server (#101)
...
Server log:
...
Client requested world (#99)
1
Sent client world (#99)
Client requested world (#100)
2
Sent client world (#100)
Client requested world (#101)
2
Sent client world (#101)
...
您可以在此处看到,即使请求号匹配,World对象中Player对象的数量也存在明显差异。
以下是来自World和Player类的重要内容:
public class World implements Serializable
{
public ArrayList<Room> rooms;
public ArrayList<Player> players;
private QuickMaths qm;
public class Player implements Serializable
{
private double xPos;
private double yPos;
private Color color;
int id;
...
很抱歉,这是一个长期而又简单的问题。我不确定这是参考问题还是其他网络怪癖,但这确实使我发疯。预先感谢。