所以我想使用套接字在Java中制作纸牌游戏。我有这个" PlayerState"保持所有在大厅或准备好比赛的球员的对象。问题是即使服务器为所有客户端发送相同的对象,所有客户端都收到不正确数据的不同对象...让我解释一下
所以这是SERVER中发送Object的方法:
private void sendToAll(PlayersState playersState){
resetLists(playersState.getLobbyPlayers(),playersState.getReadyPlayer());
Iterator it = clientOutputStreams.iterator();
while (it.hasNext())
try {
ObjectOutputStream writer = (ObjectOutputStream) it.next();
writer.writeObject(playersState);
writer.flush();
System.out.println(playersState.getLobbyPlayers());
} catch (Exception ex) {
}
}
这是接收Object
的CLIENT中的方法private void whileChatting() throws IOException {
sendMessage("&nume"+nume);
do {
try {
Object object = input.readObject();
if(object instanceof String)
showMessage("\n" + (String) object);
else if(object instanceof PlayersState){
System.out.println(((PlayersState) object).getLobbyPlayers());
PlayersState actualPlayerState = new PlayersState();
actualPlayerState.setReadyPlayer(((PlayersState) object).getReadyPlayer());
actualPlayerState.setLobbyPlayers(((PlayersState) object).getLobbyPlayers());
resetLists(actualPlayerState.getLobbyPlayers(),actualPlayerState.getReadyPlayer());
}
} catch (ClassNotFoundException var2) {
showMessage("Unknown data received!");
}
} while(!message.equals("SERVER - END"));
}
这是对象(在CLIENT和SERVER中均可用)
package sample;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public class PlayersState implements Serializable{
private static final long serialVersionUID = 7526472295622776147L;
private List<String> LobbyPlayers;
private List<String> ReadyPlayer;
public PlayersState(){
LobbyPlayers = new ArrayList<>();
ReadyPlayer = new ArrayList<>();
}
public void removeFrom(String name, List<String> list){
if(list.contains(name))
list.remove(name);
}
public void addTo(String name, List<String> list){
list.add(name);
}
public List<String> getLobbyPlayers() {
return LobbyPlayers;
}
public void setLobbyPlayers(List<String> lobbyPlayers) {
LobbyPlayers = lobbyPlayers;
}
public List<String> getReadyPlayer() {
return ReadyPlayer;
}
public void setReadyPlayer(List<String> readyPlayer) {
ReadyPlayer = readyPlayer;
}
}
如果我一个接一个地打开3个客户端,请说出user1 user2和user3来自SERVER的println的输出将是:
[user1, user2, user3]
[user1, user2, user3]
[user1, user2, user3]
这里一切都很正常。但这是客户收到的:
客户端1(user1):
[user1]
[user1]
[user1]
客户端2(user2)
[user1,user2]
[user1,user2]
客户端3(用户3)
[user1,user2,user3]
为什么客户端没有收到所有相同的数据?
答案 0 :(得分:-1)
PlayersState
不是一个可变类,所以你应该在multiple-thread.like同步它:
tresetLists(playersState.getLobbyPlayers(),playersState.getReadyPlayer());
Iterator it = clientOutputStreams.iterator();
byte[] sendBytes=null;
synchronized (playersState) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(playersState);
sendBytes = bos.toByteArray();
oos.close();
}
while (it.hasNext())
try {
ObjectOutputStream writer = (ObjectOutputStream) it.next();
writer.write(sendBytes);
writer.flush();
System.out.println(playersState.getLobbyPlayers());
} catch (Exception ex) {
}
在上面的代码中,为了提高性能并减少锁定的保持时间,我们锁定playersState
并将其序列化为sendBytes
数组一次。
当然,您应该随时同步playersState
,例如在其他线程上调用getLobbyPlayers
和getReadyPlayer
。