【发布时间】:2012-05-05 00:30:06
【问题描述】:
我正在编写服务器/客户端游戏。我的客户端向服务器发送一条消息,服务器应该将该消息分发给连接到服务器的所有其他客户端。我遇到的问题是,当我调用 ois.readObject() (其中 ois 是从 ServerSocket accept() 调用创建的 ObjectInputStream )时,它只返回我写入客户端相应 ObjectOutputStream 的第一个值.
这是我的服务器为每个连接的客户端创建的线程的代码。
@Override
public void run() {
Iterator<ClientThread> itr = null;
ClientThread ct = null;
Object recObj = null;
try {
oos.writeObject(id);
oos.flush();
while(oos != null && ois != null) {
recObj = ois.readObject();
System.out.println(recObj);
if(recObj instanceof Player) {
System.out.println("[" + id + "] Recieved player from client.");
player = (Player) recObj;
Server.playerMap.put(player.getId(), player);
if(player == null) {
System.out.println("Player " + player.getId() + " has joined the server.");
}
itr = Server.threadList.iterator();
while(itr.hasNext()) {
ct = itr.next();
if(!(ct.id == this.id)) {
ct.oos.writeObject(recObj);
ct.oos.flush();
System.out.println("Sending " + (Player) recObj + " to client " + ct.id + "!");
} else {
System.out.println("Don't send stuff to " + ct.id + " or we get an infinite loop!");
}
}
} else {
System.err.println("Recieved something other than a Player object.");
}
}
} catch (IOException e) {
System.err.println("[INFO] " + e.getLocalizedMessage());
} catch (ClassNotFoundException e) {
System.err.println(e.getLocalizedMessage());
e.printStackTrace();
}
cleanup();
}
此代码适用于每个客户端创建的线程。
@Override
public void run() {
Object recObj = null;
Player newPlayer = null;
try {
recObj = client.ois.readObject();
if(recObj instanceof Integer) {
client.player = new Player((Integer) recObj);
client.playerMap.put(client.player.getId(), client.player);
} else {
System.err.println("First object recieved from server was not of type Integer.");
System.err.println("No valid id has been set.");
}
while(client.ois != null) {
recObj = client.ois.readObject();
if(recObj instanceof Player) {
newPlayer = (Player) recObj;
System.out.println("Recieved " + newPlayer + "!");
client.playerMap.put(newPlayer.getId(), newPlayer);
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
附:我意识到我不需要刷新 ObjectOutputStream,但这只是一个测试的想法。
【问题讨论】:
-
不确定这种方式的线程是否良好,我会将客户端的消息排入处理该客户端的线程中,但它基本上也应该在您的场景中工作。 (希望您不要将新玩家发送给尚未收到其 id 的客户端)。您的发送循环可能会被未读取的客户端阻止,请在写入前后使用 println 进行验证。
标签: java sockets objectoutputstream