我有简单的基于套接字的客户端 - 服务器应用程序,每个连接都有自己的线程。 目前的计划是这样的:
问题是每个线程都连接并接收板对象,但是当它再次发送时,它再次发送相同的对象,但在服务器端,对象的行为正确。
public static void main(String[] args) {
Board gameBoard = new Board();
ActiveSessions sessions = new ActiveSessions();
Broadcaster broadcaster = new Broadcaster(sessions, gameBoard);
try {
ServerSocket socket = new ServerSocket(1234);
// Timeout after what no more new connections are not accepted.
socket.setSoTimeout(30 * 1000);
logger.info("Server started on port " + socket.getLocalPort());
while (true) {
SessionHandler session = new SessionHandler(socket.accept(), gameBoard, broadcaster);
sessions.addSession(session);
session.start();
}
} catch (SocketTimeoutException e1) {
logger.info("No more new connecions are accpeted, start game or end");
gameBoard.setGameState(GameState.PLAYING);
logger.info("Set the gamestate to " + gameBoard.getGameState());
} catch (IOException e) {
logger.info("I/O error " + e.getMessage());
}
SessionHandler,每个连接都有自己的线程 包服务器;
import game.Board;
import game.Turn;
import java.io.EOFException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.SocketException;
import java.util.logging.Logger;
public class SessionHandler extends Thread {
private Board gameBoard;
private Socket socket;
private Broadcaster broadcaster;
private boolean firstConnect = true;
private ObjectOutputStream out;
private ObjectInputStream in;
private static final Logger logger = Logger.getLogger(SocketServer.class.getName());
public SessionHandler(Socket socket) {
this.socket = socket;
}
public SessionHandler(Socket accept, Board gameBoard, Broadcaster broadcaster) {
this(accept);
this.gameBoard = gameBoard;
this.broadcaster = broadcaster;
}
@Override
public void run() {
try {
out = new ObjectOutputStream(socket.getOutputStream());
in = new ObjectInputStream(socket.getInputStream());
while (true) {
Turn turn = (Turn) in.readObject();
if (turn != null) {
if (firstConnect) {
gameBoard.addPlayer(turn.getWhoseTurn());
firstConnect = false;
}
// Add the turn to game board and make validation
gameBoard.increaseTurns();
broadcaster.send();
}
System.out.println("Turns made " + gameBoard.getTurns() + " players " + gameBoard.getPlayers() + " dice score " + turn.getDiceScore());
}
} catch (EOFException e1) {
logger.warning("Problem reading the object output");
} catch (SocketException e) {
if ("Connection reset".equals(e.getMessage())) {
System.out.println("Client disconnected, performing cleanup");
} else {
logger.warning("Connection between client lost " + Thread.currentThread());
}
} catch (Exception e) {
e.printStackTrace();
System.exit(-1);
}
}
public void sendTheGameBoard() {
try {
out.writeObject(this.gameBoard);
out.flush();
} catch (IOException e) {
logger.warning("Problem with sending game board object " + e.getMessage());
}
}
}
class Broadcaster {
private ActiveSessions activeSessions;
public Broadcaster(ActiveSessions aa, Board board) {
this.activeSessions = aa;
}
public void send() {
// Broadcast board forever
synchronized (activeSessions) {
Iterator<SessionHandler> active = activeSessions.iterator();
while (active.hasNext()) {
SessionHandler session = active.next();
if (!session.isAlive()) {
active.remove();
session.interrupt();
} else {
session.sendTheGameBoard();
}
}
}
}
}
答案 0 :(得分:4)
阅读http://java.sun.com/javase/technologies/core/basic/serializationFAQ.jsp#handle。 ObjectOutputStream有一个缓存,以避免多次发送同一个对象。您必须重置流才能再次发送副本。