java - 通过 Java 套接字发送对象
问题描述
我有一个班级名称播放器
public JLabel imagen;
public String Nombre;
public Player(int x, int y, int width, int height, Icon icono, String name){
imagen = Player(x, y, width, height, icono);
Nombre = name;
}
public JLabel Player(int x, int y, int width, int height, Icon icono){
JLabel imagen = new JLabel(icono);
imagen.setLocation(x, y);
imagen.setSize(width, height);
return imagen;
}
(用于创建新玩家)
我也有一个客户端类:
public class Cliente implements Runnable {
String host;
int puerto;
Player mensaje;
public Cliente(int purto, Player mensaje, String host){
this.puerto = purto;
this.mensaje = mensaje;
this.host = host;
}
@Override
public void run() {
DataOutputStream out;
try {
Socket sc = new Socket(host, puerto);
out = new DataOutputStream(sc.getOutputStream());
ObjectOutputStream objectOutputStream = new ObjectOutputStream(out);
objectOutputStream.writeObject(mensaje);
sc.close();
} catch (IOException ex) {
System.out.println(ex);
}
}
}
我正在使用 objectOutputStream 但它说它
“java.io.NotSerializableException:objects.Player”
我想将我的播放器发送到服务器,但它说异常!
另外,如果您需要这里是服务器类
public class Servidor extends Observable implements Runnable {
int puerto;
public Servidor(int puerto) {
this.puerto = puerto;
}
@Override
public void run() {
ServerSocket servidor = null;
Socket sc = null;
DataInputStream in;
try {
servidor = new ServerSocket(puerto);
System.out.println("server started");
while (true) {
sc = servidor.accept();
in = new DataInputStream(sc.getInputStream());
ObjectInputStream input = new ObjectInputStream(in);
Player players = null;
try {
players = (Player) input.readObject();
System.out.println(players.Nombre);
} catch (ClassNotFoundException ex) {
}
this.setChanged();
this.notifyObservers(players);
this.clearChanged();
sc.close();
}
} catch (IOException ex) {
}
}
}
如果你想要这里是发送请求到客户端类的代码行
Cliente c = new Cliente(5000, new Player(x, y, width, height, icon, "name of the player"), "the ip");
Thread t = new Thread(c);
t.start();
解决方案
看起来您忘记使 Player 对象可序列化,因此代码正在抛出java.io.NotSerializableException
如果您需要通过网络发送一些对象,那么该对象需要是可序列化的。
序列化是获取对象的内存数据结构并将其编码为串行(因此称为术语)字节序列的过程。然后可以将该编码版本保存到磁盘、通过网络连接发送或以其他方式传送给接收者。(来自维基百科)
我已经更新了代码
播放器.java
import java.io.Serializable;
import javax.swing.Icon;
import javax.swing.JLabel;
public class Player implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
public JLabel imagen;
public String Nombre;
public Player(int x, int y, int width, int height, Icon icono, String name) {
imagen = Player(x, y, width, height, icono);
Nombre = name;
}
public JLabel Player(int x, int y, int width, int height, Icon icono) {
JLabel imagen = new JLabel(icono);
imagen.setLocation(x, y);
imagen.setSize(width, height);
return imagen;
}
}
客户端.java
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.Socket;
public class Cliente implements Runnable {
String host;
int puerto;
Player mensaje;
public Cliente(int purto, Player mensaje, String host) {
this.puerto = purto;
this.mensaje = mensaje;
this.host = host;
}
// @Override
public void run() {
DataOutputStream out;
try {
Socket sc = new Socket(host, puerto);
out = new DataOutputStream(sc.getOutputStream());
ObjectOutputStream objectOutputStream = new ObjectOutputStream(out);
objectOutputStream.writeObject(mensaje);
sc.close();
} catch (IOException ex) {
System.out.println(ex);
}
}
public static void main(String[] args) {
Cliente c = new Cliente(5000, new Player(1, 2, 3, 4, null,
"Holis Studios"), "localhost");
Thread t = new Thread(c);
t.start();
}
}
服务端.java
import java.io.DataInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Observable;
public class Servidor extends Observable implements Runnable {
int puerto;
public Servidor(int puerto) {
this.puerto = puerto;
}
// @Override
public void run() {
ServerSocket servidor = null;
Socket sc = null;
DataInputStream in;
try {
servidor = new ServerSocket(puerto);
System.out.println("server started");
while (true) {
sc = servidor.accept();
in = new DataInputStream(sc.getInputStream());
ObjectInputStream input = new ObjectInputStream(in);
Player players = null;
try {
players = (Player) input.readObject();
System.out.println(players.Nombre);
} catch (ClassNotFoundException ex) {
}
this.setChanged();
this.notifyObservers(players);
this.clearChanged();
sc.close();
}
} catch (IOException ex) {
}
}
public static void main(String[] args) {
Servidor server = new Servidor(5000);
Thread t = new Thread(server);
t.start();
}
}
编译代码:
javac.exe -cp . Player.java
javac.exe -cp . Servidor.java
javac.exe -cp . Cliente.java
跑:
java.exe -cp . Servidor
server started
java.exe -cp . Cliente
出现在服务器控制台上的输出:
server started
Holis Studios
推荐阅读
- python - Python Pandas:通过数据框搜索正则表达式
- r - 使用语法文件打开 ASCII 数据
- parse-server - 从 AWS EB 构建主 Parse-Dashboard
- ios - 我可以在 ForEach 中使用协议数组吗?
- javascript - Return false in JavaScript If statement when value is duplicated
- c# - 防止在 Designer.cs 中分配 UserControl 公共变量
- javascript - 如何在 Angular 中使用 ngFor 获取嵌套对象数组的选定值?
- reactjs - 警告:渲染方法应该是 props 和 state 的纯函数;不允许从渲染触发嵌套组件更新
- asp.net-mvc - 在 apiController 构造函数 System.NullReferenceException:“对象引用未设置为对象的实例。”
- .net - .NET LINQ 左连接问题