Я пытаюсь написать реализацию RemoteDesktop в Java. Я использую ObjectOutputStream и ObjectInputStream через сокет для отправки данных. Для передачи данных, я использую класс я создал под названием «Пакет»:Ошибки при чтении из ObjectInputStream Java
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import javax.swing.ImageIcon;
/**
* Holds data to send over network connection
*/
class Packet<T extends Serializable> implements Serializable {
private T payload;
public Packet() {
super();
}
public Packet(T data) {
super();
setPayload(data);
}
public T getPayload() {
return payload;
}
public void setPayload(T payload) {
this.payload = payload;
}
public static void send(String message, ObjectOutputStream out) throws IOException {
out.writeObject(new Packet<>(message));
out.flush();
}
public static void send(Integer value, ObjectOutputStream out) throws IOException {
out.writeObject(new Packet<>(value));
out.flush();
}
public static void send(Block block, ObjectOutputStream out) throws IOException {
out.writeObject(new Packet<>(block));
out.flush();
}
public static void send(BufferedImage[][] images, ObjectOutputStream out) throws IOException {
//convert to ImageIcon
ImageIcon icons[][] = new ImageIcon[images.length][images[0].length];
for (int x = 0; x < images.length; x++) {
for (int y = 0; y < images[0].length; y++) {
icons[x][y] = new ImageIcon(images[x][y]);
}
}
out.writeObject(new Packet<>(icons));
out.flush();
}
}
При первой установке соединения, сервер посылает массив ImageIcon в 2-D, который содержит различные «блоки» экрана. Экран разделен на этот массив блоков. Затем сервер выполняет регулярные скриншоты и сравнивает каждый «блок» экрана с последним, чтобы увидеть, изменился ли он. Если есть изменения, то сервер отправит новую область экрана в классе под названием «Блок», который удерживает координату х и у этого блока и ImageIcon:
import java.awt.image.BufferedImage;
import java.io.Serializable;
import javax.swing.ImageIcon;
/**
* Holds an image and its x and y coordinates on the screen
*/
class Block implements Serializable {
private ImageIcon img;
private int x;
private int y;
public Block() {
super();
}
public Block(BufferedImage image, int x, int y) {
img = new ImageIcon(image);
this.x = x;
this.y = y;
}
public Block(ImageIcon image, int x, int y) {
img = image;
this.x = x;
this.y = y;
}
public int getx() {
return x;
}
public int gety() {
return y;
}
public ImageIcon getImage() {
return img;
}
}
Вот основной код сервер
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String args[]) throws IOException {
ServerSocket s = new ServerSocket(5000);
do {
Socket c;
ObjectOutputStream out;
ObjectInputStream in;
//start listening
echo("Listening on port: 5000");
//accept connection
c = s.accept();
echo("Connected to client at address " + c.getInetAddress().getHostAddress());
//open IO streams
out = new ObjectOutputStream(c.getOutputStream());
in = new ObjectInputStream(c.getInputStream());
ServerSession rdsession = new ServerSession(in, out); //start session
} while (true);
}
private static void err(String message) {
//prints error message and exits
System.err.println(message);
System.exit(1);
}
private static void echo(String message) {
//prints message
System.out.println(message);
}
}
Таким образом, когда соединение установлено, сервер создает экземпляр класса «ServerSession». Этот класс обрабатывает сеанс RD, определяя, когда отправлять новые изображения в объект «Блок». Когда ему нужно обновить блок для клиента, он использует метод Packet.send (Block, ObjectOutputStream).
Объект считывает объекты из потока, используя этот код:
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import javax.swing.ImageIcon;
public class Client {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Socket c;
ObjectOutputStream out;
ObjectInputStream in;
String serverIP = "127.0.0.1"; //replace with server IP
int port = 5000;
//open connection and streams
c = new Socket(serverIP, port);
out = new ObjectOutputStream(c.getOutputStream());
in = new ObjectInputStream(c.getInputStream());
ClientSession cs = null;
do {
Packet<?> p;
Object o = in.readObject();
if (o instanceof Packet) {
p = (Packet<?>) o;
} else {
continue;
}
if (p.getPayload() instanceof String) { //check if string
echo("Server>" + p.getPayload());
} else if (p.getPayload() instanceof Block) { //check if block
Block b = (Block) p.getPayload();
if (cs != null) {
cs.setImage(b.getImage(), b.getx(), b.gety());
}
} else if (p.getPayload() instanceof ImageIcon[][]) { //check if 2-D image array
cs = new ClientSession(in, out, (ImageIcon[][]) p.getPayload()); //create session with image array
}
} while (true);
}
private static void err(String message) {
System.err.println(message);
System.exit(1);
}
private static void echo(String message) {
System.out.println(message);
}
}
Класс ClientSession просто хранит изображения экрана и ручки графического интерфейса пользователя.
Когда я запускаю сервер и клиент вместе, я получаю множество ошибок после отправки исходного массива ImageIcon [] [] каждый раз, когда клиент пытается прочитать экземпляр «Блок». Это ошибки, которые регулярно выброшенные:
1:
Exception in thread "main" java.io.InvalidClassException: Block; invalid descriptor for field
at java.io.ObjectStreamClass.readNonProxy(ObjectStreamClass.java:710)
at java.io.ObjectInputStream.readClassDescriptor(ObjectInputStream.java:828)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1599)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1515)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1769)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1348)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1989)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1913)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1796)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1348)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)
at Client.main(Client.java:46)
Caused by: java.lang.IllegalArgumentException: illegal signature
at java.io.ObjectStreamField.<init>(ObjectStreamField.java:122)
at java.io.ObjectStreamClass.readNonProxy(ObjectStreamClass.java:708)
... 11 more
2:
Exception in thread "main" java.io.InvalidClassException: Block; invalid descriptor for field sq ~ sq
at java.io.ObjectStreamClass.readNonProxy(ObjectStreamClass.java:710)
at java.io.ObjectInputStream.readClassDescriptor(ObjectInputStream.java:828)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1599)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1515)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1769)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1348)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1989)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1913)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1796)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1348)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1989)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1913)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1796)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1348)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1989)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1913)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1796)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1348)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)
at Client.main(Client.java:25)
Caused by: java.lang.IllegalArgumentException: illegal signature
at java.io.ObjectStreamField.<init>(ObjectStreamField.java:122)
at java.io.ObjectStreamClass.readNonProxy(ObjectStreamClass.java:708)
... 19 more
3:
Exception in thread "main" java.io.EOFException
at java.io.DataInputStream.readInt(DataInputStream.java:392)
at java.io.ObjectInputStream$BlockDataInputStream.readInt(ObjectInputStream.java:2818)
at java.io.ObjectInputStream.readInt(ObjectInputStream.java:969)
at javax.swing.ImageIcon.readObject(ImageIcon.java:481)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1017)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1891)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1796)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1348)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1989)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1913)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1796)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1348)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1989)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1913)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1796)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1348)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)
at Client.main(Client.java:25)
4:
Exception in thread "main" java.io.StreamCorruptedException: invalid type code: 73
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1518)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1769)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1348)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1989)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1913)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1796)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1348)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1989)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1913)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1796)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1348)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)
at Client.main(Client.java:25)
Спасибо, что нашли время, чтобы прочитать это сообщение. Любые советы будут очень признательны. Благодаря!
Ваш вопрос очень длинный. Не могли бы вы решить эту проблему? –
Проводка SSCCE поможет: http://sscce.org/ – Kon
Что делает клиентская речь с потоками ввода и вывода? – jtahlborn