Я пытаюсь создать многопользовательскую игру с игровым сервером, работающим не более чем с 4 клиентами, используя java Socket и ServerSocket.В этом коде я ограничил число клиентов до 1 для тестирования и использовал модель блокирующего ввода-вывода для игрока и сервера.
Поток игрового сервера (реализует Runnable) получает объект Snake для snake [i] 'и переменная char для dirInput ' от каждого клиента, использующего поток ввода сокета, и отправляет массив объектов Snake snake 'и объект Apple apple 'с использованием потока вывода сокета.И объект Snake, и объект Apple являются сериализуемыми.
Здесь массив clientSocket состоит из всех подключенных клиентских сокетов, и эти сокеты не закрываются, пока игрок не завершит соединение (что означает, что соединение выполняется с одним сокетом для всего игрового процесса для каждого игрока), доска объект расширяет JComponent для игровой графики (показывает игровой процесс).
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 (реализует Runnable) отправляет объект Snake mySnake 'и' переменная char inputControl 'на сервер и получает переменную int для playerNumber ', массив объектов Snake для board.snakes 'и' Appleобъект для board.apple 'с сервера.
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();
}
}
}
Проблема заключается в том, что когда я запускаю игровой сервер и клиент и пытаюсь установить связь, оба потока игрового сервера и поток клиента игрока зависаютво время общения.
Когда я отлаживал, поток игрового сервера зависал при чтении ввода символов (dirInput) из потока клиента, а поток клиента зависал при чтении ввода int (playerNumber) из потока игрового сервера.Видя, что оба потока застряли с InputStream, я подумал, что во время использования InputStream произошла тупиковая ситуация, поскольку оба потока пытаются использовать InputStream.Но я не уверен, действительно ли происходит тупик или нет.
Как я могу заставить оба потока общаться?Должен ли я использовать неблокирующую модель ввода / вывода для потока игрового сервера и потока клиента игрока?