Неверная передача объекта серверу java
Я пишу онлайн игру и возникла проблема: пересылка объекта клавиатуры. Клиент отправляет экземпляр, у которого в свойствах указано, что клавиша нажата, а сервер получает объект, у которого указано в свойствах, что клавиша отпущена.
Написал небольшой пример, иллюстрирующий это. Кто сможет помочь, буду благодарен.
Код:
тестовый класс:
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Arrays;
public class TCPPhoneSerialization {
private static final int PORT = 26781;
private static final String ADDRESS = "127.0.0.1";
public static void main(String[] args) {
new Thread(() -> {
try (ServerSocket server = new ServerSocket(PORT)) {
System.out.println("Server started on port: " + PORT);
TCPSerPhone1 client = new TCPSerPhone1(server);
System.out.println("Server: Client connected with ip address: " + client.getIp());
KeysListener keysboard;
while (true) {
Object res = client.readObject();
//System.out.println(res.getClass());
keysboard = (KeysListener) res;
System.out.println("Server: " + Arrays.toString(keysboard.keys));
Thread.sleep(200);
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}).start();
new Thread(() -> {
KeysListener keys = new KeysListener();
JFrame keyReader = new JFrame();
keyReader.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
keyReader.setBounds(new Rectangle(200, 200, 400, 400));
keyReader.setVisible(true);
keyReader.addKeyListener(keys);
try (TCPSerPhone1 client = new TCPSerPhone1(ADDRESS, PORT)) {
System.out.println("Client: Player connected to server with ip: " + ADDRESS + " on port " + PORT);
while (true) {
client.writeObject(keys);
System.out.println("Client: " + Arrays.toString(keys.keys));
Thread.sleep(200);
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
class KeysListener implements KeyListener, Serializable {
//все клавиши, которыек нам нужны
public final boolean[] keys = new boolean[4];
public KeysListener() {
}
public void keyPressed(KeyEvent event) {
if (event.getKeyChar() == 'a')
keys[0] = true;
if (event.getKeyChar() == 'd')
keys[1] = true;
if (event.getKeyChar() == 's')
keys[2] = true;
if (event.getKeyChar() == 'w')
keys[3] = true;
}
public void keyReleased(KeyEvent event) {
if (event.getKeyChar() == 'a')
keys[0] = false;
if (event.getKeyChar() == 'd')
keys[1] = false;
if (event.getKeyChar() == 's')
keys[2] = false;
if (event.getKeyChar() == 'w')
keys[3] = false;
}
public void keyTyped(KeyEvent event) {
}
}
class TCPSerPhone1 implements Closeable {
private final Socket socket; //сам сокет
//потоки для чтения / записи
private final ObjectInputStream objectReader;
private final ObjectOutputStream objectWriter;
//закрыт ли сокет (для сервера)
public boolean closed = false;
//конструктор для клиента
public TCPSerPhone1(String ip, int port) {
try {
this.socket = new Socket(ip, port);
this.objectWriter = createObjectWriter();
this.objectReader = createObjectReader();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
//конструктор для сервера
public TCPSerPhone1(ServerSocket server) {
try {
this.socket = server.accept();//ожидание клиентов
this.objectWriter = new ObjectOutputStream(socket.getOutputStream());
this.objectReader = new ObjectInputStream(socket.getInputStream());
objectWriter.flush();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
//получение ip адреса в виде строки через сокет
public String getIp() {
return socket.getInetAddress().getHostAddress();
}
//отправка сообщения
public int writeObject(Serializable obj) {
if (!closed) {
try {
objectWriter.writeObject(obj);
objectWriter.flush();
return 0;
} catch (IOException e) {
e.printStackTrace();
return -1; //попытка отправки оффлайн киенту
}
}
return -2; //сокет сервера закрыт
}
public Object readObject() {
if (!closed) {
try {
return objectReader.readObject();
} catch (IOException | ClassNotFoundException e) {
//e.printStackTrace();
return "-1"; //попытка отправки оффлайн киенту
}
}
return "-2"; //сокет сервера закрыт
}
//создание потока ввода
private ObjectInputStream createObjectReader() throws IOException {
return new ObjectInputStream(socket.getInputStream());
}
//создание потока вывода
private ObjectOutputStream createObjectWriter() throws IOException {
return new ObjectOutputStream(socket.getOutputStream());
}
//чтобы можно было использовать try-catch with resources
@Override
public void close() throws IOException {
closed = true;
objectReader.close();
objectWriter.close();
socket.close();
}
}