I am trying to build a multiplayer game with game server operating with at most 4 clients, using java Socket and ServerSocket. I limited number of clients to 1 in this code for testing, and used Blocking I/O Model for both player and server.
Game Server Thread (implements Runnable) receives 'Snake object to snake[i]' and 'char variable to dirInput' from each client using socket input stream, and sends 'Snake object Array snake' and 'Apple object apple' using socket output stream. Both Snake object and Apple object is Serializable.
In here, clientSocket array consists all connected client Sockets, and these sockets don't close until player ends connection (which means connection is done with one socket for entire gameplay for each player). board object extends JComponent for Game Graphics (shows gameplay).
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();
}
}
}
}
Each Player Client Thread (implements Runnable) sends 'Snake object mySnake' and 'char variable inputControl' to server and receives 'int variable to playerNumber', 'Snake object Array to board.snakes' and 'Apple object to board.apple' from server.
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();
}
}
}
The problem is, when I start both game server and client and try to communicate, both Game Server Thread and Player Client Thread stucks while communicating.
When I debugged, Game Server Thread is stuck with reading char input (dirInput) from Client Thread, and Client Thread is stuck with reading int input (playerNumber) from Game Server Thread. By seeing both thread are stuck with InputStream, I thought deadlock happened while using InputStream, since both thread tries to use InputStream. But I'm not sure if deadlock is really happening or not.
How can I make both thread communicate? Should I use Nonblocking I/O model for both Game Server Thread and Player Client Thread?