我正在尝试使用java Socket和ServerSocket来构建一个游戏服务器,该服务器最多可以运行4个客户端,从而构建多人游戏。在此代码中,我将客户端数量限制为1个,以进行测试,并且对播放器和服务器都使用了阻塞I / O模型。
游戏服务器线程(可运行的实现)从每个接收“向 snake [i] 蛇的对象”和“向 dirInput 的char变量”客户使用套接字输入流,并使用套接字输出流发送“蛇对象数组蛇”和“苹果对象苹果”。 Snake对象和Apple对象都是可序列化的。
在这里, clientSocket 数组由所有已连接的客户端套接字组成,并且这些套接字在玩家结束连接之前不会关闭(这意味着每个玩家整个游戏过程都使用一个套接字进行连接)。 board 对象扩展了JComponent for Game Graphics(显示游戏玩法)。
public void run()
{
while(true)
{
//playerCount is fixed to 1 for testing
for(int i=0; i<playerCount; i++)
{
try {
//get every snake object from each player
ObjectInputStream objectInputStream = new ObjectInputStream(clientSocket[i].getInputStream());
snake[i] = (Snake)objectInputStream.readObject();
} catch (Exception e) {
e.printStackTrace();
}
}
for(int i=0; i<playerCount; i++)
{
try {
Reader charInputStream = new InputStreamReader(clientSocket[i].getInputStream());
dirInput = (char) charInputStream.read();
//DO SOMETHING WITHOUT COMMUNICATION
} catch (IOException e) {
e.printStackTrace();
}
}
for(int i=0; i<playerCount; i++)
{
try {
OutputStream outputStream = clientSocket[i].getOutputStream();
outputStream.write(i);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(clientSocket[i].getOutputStream());
objectOutputStream.writeObject(snake);
objectOutputStream.writeObject(apple);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
每个 Player客户端线程(可运行的实现)将“ Snake对象 mySnake ”和“ char变量 inputControl ”发送到服务器并接收“ int
变量,public void run() {
while(true)
{
try {
Thread.sleep(50);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(gameSocket.getOutputStream());
objectOutputStream.writeObject(mySnake);
Writer charOutputWriter = new OutputStreamWriter(gameSocket.getOutputStream());
charOutputWriter.write(inputControl);
playerNumber = gameSocket.getInputStream().read();
ObjectInputStream objectInputStream = new ObjectInputStream(gameSocket.getInputStream());
board.snakes = (Snake[])objectInputStream.readObject();
board.apple = (Apple)objectInputStream.readObject();
mySnake = board.snakes[playerNumber];
board.repaint();
} catch (Exception e) {
e.printStackTrace();
}
}
}
问题是,当我同时启动游戏服务器和客户端并尝试进行通信时,游戏服务器线程和播放器客户端线程在通信时都卡住了。
当我调试时,游戏服务器线程卡住了从客户端线程读取char输入(dirInput),而客户端线程卡住了从Game Server线程读取int输入(playerNumber)。通过看到两个线程都被InputStream阻塞,我认为使用InputStream时发生了死锁,因为两个线程都试图使用InputStream。但是我不确定僵局是否真的发生了。
如何使两个线程通信?我应该同时为游戏服务器线程和玩家客户端线程使用非阻塞I / O模型吗?
答案 0 :(得分:0)
我不确定您的实际情况!但是问题是您创建了 ObjectInputStream 多次!如果您想知道问题所在,只需创建一个扩展 java.io.InputStream 类的简单类,并通过将该类作为基础来创建 ObjectInputStream InputStream 。您会看到 ObjectInputStream 类创建时,它将尝试读取4个字节作为标头字节!因此,这意味着您丢失了一些数据,这就是线程卡住的原因! 如果有反编译器,也可以检查ObjectInputStream的代码。