如何在Java中促进服务器线程和多个客户端线程之间的通信
我正在尝试使用java套接字创建一个客户机-服务器游戏。我有一个线程服务器,它控制游戏的逻辑。我还有与服务器通信的客户端线程。我使用多个客户端处理程序线程来促进服务器到客户端的通信。我使用多个线程使用套接字与其他客户端线程通信如何在Java中促进服务器线程和多个客户端线程之间的通信,java,multithreading,sockets,Java,Multithreading,Sockets,我正在尝试使用java套接字创建一个客户机-服务器游戏。我有一个线程服务器,它控制游戏的逻辑。我还有与服务器通信的客户端线程。我使用多个客户端处理程序线程来促进服务器到客户端的通信。我使用多个线程使用套接字与其他客户端线程通信 现在,关于如何促进服务器线程和多个客户端线程之间的通信,我遇到了一个问题。例如,如果服务器选择下一个要播放的播放器,它应该如何向客户机处理程序线程发送信号,然后通过套接字与客户机线程通信?我怀疑您的客户机线程挂起了阻塞读取操作。要“释放”这些线程并让它们发送数据,您必须通
现在,关于如何促进服务器线程和多个客户端线程之间的通信,我遇到了一个问题。例如,如果服务器选择下一个要播放的播放器,它应该如何向客户机处理程序线程发送信号,然后通过套接字与客户机线程通信?我怀疑您的客户机线程挂起了阻塞读取操作。要“释放”这些线程并让它们发送数据,您必须通过thread.interrupt()中断它们。(这将导致阻塞读取抛出InterruptedException。)
然而,我自己也写了一些网络游戏,我真的建议你去研究一下,尤其是这个类。使用这个类,您可以轻松地使整个服务器成为单线程的。在同步所有这些客户端线程时,这将为您节省很多麻烦。我认为使用现有的通信基础设施(如ActiveMQ)来处理低级管道问题非常有用,并允许您在更高的概念级别上处理游戏设计问题,而不是处理低级复杂 话虽如此。如果我了解你,那么你有一个多线程的游戏客户端,其中一个线程处理与服务器的通信。在服务器上,每个客户端和游戏服务器逻辑都有一个comms线程
我只使用套接字进行远程通信,使用队列进行服务器线程之间的通信。在队列上来回发送不可变对象(或副本),这样您就不需要同步对消息中数据的访问。作为同步的基础,您可以在套接字或BlockingQueue上进行阻塞,然后您不需要手动同步,但是这需要仔细的协议设计 我以前用以下方法做过。我有一个服务器插座
public Server(int port, int numPlayers) {
game = new PRGameController(numPlayers);
try {
MessageOutput.info("Opening port on " + port);
ServerSocket clientConnectorSocket = new ServerSocket(port);
MessageOutput.info("Listening for connections");
while (!game.isFull()) {
// block until we get a connection from a client
final Socket client = clientConnectorSocket.accept();
MessageOutput.info("Client connected from " + client.getInetAddress());
Runnable runnable = new Runnable() {
public synchronized void run() {
PRGamePlayer player = new PRGamePlayer(client, game);
}
};
new Thread(runnable).start();
}
} catch (IOException io) {
MessageOutput.error("Server Connection Manager Failed...Shutting Down...", io);
// if the connection manager fails we want to closedown the server
System.exit(0);
}
}
那么在客户端,我有这样的东西
public void connect(String ip) {
try {
comms = new Socket(ip, 12345);
comms.setTcpNoDelay(true);
// get the streams from the socket and wrap them round a ZIP Stream
// then wrap them around a reader and writer, as we are writing strings
this.input = new CompressedInputStream(comms.getInputStream());
this.output = new CompressedOutputStream(comms.getOutputStream());
this.connected = true;
startServerResponseThread();
} catch (IOException e) {
ui.displayMessage("Unable to connect to server, please check and try again");
this.connected = false;
}
if (connected) {
String name = ui.getUserInput("Please choose a player name");
sendXML(XMLUtil.getXML(new NameSetAction(name, Server.VERSION)));
}
}
/**
* This method sets up the server response thread. The thread, sits patiently
* waiting for input from the server, in a seperate thread, so not to hold
* up any client side activities. When data is recieved from the server
* it is processed, to perform the appropriate action.
*/
public void startServerResponseThread() {
// create the runnable that will be used by the serverListenerThread,
// to listen for requests from the server
Runnable runnable = new Runnable() {
public void run () {
try {
// loop forever, or until the server closes the connection
while (true) {
processRequest(input.readCompressedString());
}
} catch (SocketException sx) {
MessageOutput.error("Socket closed, user has shutdown the connection, or network has failed");
} catch (IOException ex) {
MessageOutput.error(ex.getMessage(), ex);
} catch (Exception ex) {
MessageOutput.error(ex.getMessage(), ex);
} finally {
(PRClone.this).connected = false;
// only shutdown the server if the listener thread has not already been
// destroyed, otherwise the server will have already been shutdown
if (serverListenerThread != null) {
// shutdown the thread and inform the application the communications has closed
MessageOutput.debug("Shutting down server listener Thread");
}
}
}
};
// create the thread
serverListenerThread = new Thread(runnable);
// start the thread
serverListenerThread.start();
}
客户机能够通过outputstream向服务器发送请求,并从输入流读取服务器数据
服务器可以接受来自客户端的请求,并在GameController中进行处理,还可以使用outputstream(同样在GameController中)从服务器发送通知
编辑:另外,我应该注意,我的所有通信都是通过XML完成的,客户端或服务器上的控制器解码XML并执行相关请求
希望这有帮助。它确实为我做了这项工作,并使我的多人游戏运行良好。我做的几乎完全相同!:-)