我目前正在尝试用Java创建一个多人游戏,最多可以有五个玩家一起玩。 问题是,当我尝试将多个客户端连接到服务器时,出现异常,并且服务器不再工作。 一次只有一个客户,一切正常。
所以我需要的是一个服务器,一次最多可以处理五个玩家,并且客户端应始终从该服务器获取一些新的游戏数据。 每隔几秒钟(已连接的播放器等)。 以下代码中的“游戏数据”是我通过对象流发送的字符串。 通常,我会发送一个包含所有游戏数据的对象,但是使用字符串,我会遇到相同的问题。
我正在努力解决一个问题,即几天之内只有一个客户端可以连接而没有任何错误发生,并且我没有找到解决问题的方法。 我看到有诸如java.nio或ExecutorService之类的东西,但是我并不太了解,所以我不知道它们是否可以提供帮助。
我制作了一个较小的程序,该程序模拟了我在较大程序中遇到的相同问题。 要启动服务器,需要启动GameMultiPlayerCreate.java类,对于客户端,则需要启动Client.java类。
我是Socket的新手,所以如果不需要某些东西或可以做一些更好的事情,请告诉我。
所以当我连接两个或多个客户端时出现的错误是:
java.io.StreamCorruptedException: invalid stream header: 00050131
at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
at java.io.ObjectInputStream.<init>(Unknown Source)
at Server.waitForData(Server.java:89) //I highlighted that in the code with a comment
at Server.loopWaitForData(Server.java:49)
at Server.run(Server.java:34)
at java.lang.Thread.run(Unknown Source)
public class GameMultiPlayerCreate {
ServerSocket socketServer = null;
static String settingIp = "localhost";
static String settingPort = "22222";
static byte settingPlayers = 5;
public static int connectedPlayers = 0;
public static void main(String[] args) {
try {
GameMultiPlayerCreate objGameMultiPlayerCreate = new GameMultiPlayerCreate();
objGameMultiPlayerCreate.createServer();
} catch (NumberFormatException | IOException | InterruptedException e) {
e.printStackTrace();
}
}
public void createServer() throws NumberFormatException, UnknownHostException, IOException, InterruptedException {
while (connectedPlayers < settingPlayers) {
socketServer = new ServerSocket(Integer.parseInt(settingPort), 8, InetAddress.getByName(settingIp));
System.out.println("Server is waiting for connection...");
Socket socket = socketServer.accept();
new Thread(new Server(socket)).start();
Thread.sleep(5000);
socketServer.close();
}
}
}
public class Server implements Runnable {
protected static Socket socket = null;
private int loops;
private int maxLoops = 10;
private int timeout = 10000;
protected static boolean killThread = false;
private boolean authenticated = true; //true for testing
protected static String ip;
protected static int port;
public Server(Socket socket) throws IOException {
Server.socket = socket;
}
public void run() {
try {
socket.setSoTimeout(timeout);
} catch (SocketException e) {
System.out.println("Error while trying to set Socket timeout. ");
System.out.println("Closing Thread..." + Thread.currentThread());
disconnectClient();
}
if (!killThread) {
GameMultiPlayerCreate.connectedPlayers = GameMultiPlayerCreate.connectedPlayers + 1;
loopWaitForData();
}
}
private void disconnectClient() {
System.out.println("Kicking Client... " + Thread.currentThread());
killThread = true;
GameMultiPlayerCreate.connectedPlayers = GameMultiPlayerCreate.connectedPlayers - 1;
}
public void loopWaitForData() {
while (!killThread) {
System.out.println(maxLoops + ", " + loops);
if (maxLoops - loops > 0) {
try {
waitForData();
} catch (SocketTimeoutException e) {
System.out.println("Error occurred while waiting for Data. Thread disconnected? Sending reminder. " + Thread.currentThread());
if (!authenticated) {
System.out.println("Kicking Client: Not authenticated");
disconnectClient();
} else {
commandReminder();
}
} catch (ClassNotFoundException | IOException e) {
loops = loops + 1;
System.out.println("Error occurred while waiting for Data. Waiting for more Data. " + Thread.currentThread());
e.printStackTrace();
loopWaitForData();
}
} else if (maxLoops - loops == 0) {
System.out.println("Error occurred while waiting for Data. Maximum trys reached. Disbanding connection. " + Thread.currentThread());
disconnectClient();
loops = loops + 1;
} else {
System.out.println("Closing Thread..." + Thread.currentThread());
disconnectClient();
}
}
}
private void commandReminder() {
System.out.println("Reminder");
try {
String code = new String("0");
ObjectOutputStream outputObject = new ObjectOutputStream(Server.socket.getOutputStream());
outputObject.writeObject(code);
} catch (IOException e) {
System.out.println("Error occurred while trying to authenticate Client: " + e + " in " + Thread.currentThread());
}
}
public void waitForData() throws IOException, ClassNotFoundException {
String code;
System.out.println("Waiting for Data...");
//Next line is where the error occurres
ObjectInputStream inputObject = new ObjectInputStream(socket.getInputStream());
while ((code = (String) inputObject.readObject()) != null) {
System.out.println("Received Data...");
System.out.println("Input received: " + code);
return;
}
}
}
public class Client {
public static Socket socket = new Socket();
private int loops = 0;
private int maxLoops = 10;
private static boolean killThread = false;
private String ip;
private int port;
public Client(String receivedIp, String receivedPort) {
ip = receivedIp;
port = Integer.parseInt(receivedPort);
try {
System.out.println("Trying to connect to Server...");
socket.connect(new InetSocketAddress(ip, port));
System.out.println("Connected!");
} catch (IOException e) {
System.out.println("Error occurred while trying to connect to Server.");
}
loopWaitForData();
}
public static void main(String[] args) {
@SuppressWarnings("unused")
Client objClient = new Client("localhost", "22222");
}
public void loopWaitForData() {
while (!killThread) {
System.out.println(maxLoops + ", " + loops);
if (maxLoops - loops > 0) {
try {
waitForData();
} catch (IOException | ClassNotFoundException e) {
loops = loops + 1;
try {
Thread.sleep(2000);
} catch (InterruptedException e1) {
}
System.out.println("Error occurred while waiting for Data. Waiting for more Data. " + Thread.currentThread());
e.printStackTrace();
loopWaitForData();
}
} else if (maxLoops - loops == 0){
System.out.println("Error occurred while waiting for Data. Maximum trys reached. Disbanding connection. " + Thread.currentThread());
try {
socket.close();
} catch (IOException e) {
System.out.println("Failed to close Socket " + Thread.currentThread());
}
loops = loops + 1;
} else {
System.out.println("Closing Thread..." + Thread.currentThread());
killThread = true;
}
}
}
public void waitForData() throws IOException, ClassNotFoundException {
InputStream input = socket.getInputStream();
ObjectInputStream inputObject = new ObjectInputStream(input);
String code;
System.out.println("Waiting for Data...");
while ((code = (String) inputObject.readObject()) != null) {
System.out.println("Received Data...");
System.out.println("Input received: " + code);
answer();
return;
}
}
private void answer() {
try {
String code = new String("1");
ObjectOutputStream outputObject = new ObjectOutputStream(socket.getOutputStream());
outputObject.writeObject(code);
} catch (IOException e) {
System.out.println("Error occurred while trying to answer: " + e + " in " + Thread.currentThread());
}
}
}