我正在为一个学校的项目工作,我正在使用套接字制作一款益智游戏。对于图像绘制,我找到了this代码。我想使用版本3,因为我不需要所有功能,例如图形。
现在,我的套接字已正确设置,但是不幸的是,使用的ScribbleCanvas
(来自上面的链接)无法序列化(或看起来是这样)。有没有办法使它像这样,或者通过ObjectOutputStream
发送它呢?速度并不是真正的问题,因为它只能在本地运行,目前正在localhost上进行测试,因此它不是最有效的方式。
编辑:我对错误所在的程序进行了快速建模,也许我在其他地方犯了一些错误。
import java.awt.BorderLayout;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import javax.swing.JFrame;
import javax.swing.JPanel;
import scribble3.ScribbleCanvas;
public class Main extends JFrame{
/* Scribble */
public static ScribbleCanvas myCanvas;
public static JPanel scribblePanel;
/* TCP */
public static ServerSocket hostServer;
public static Socket socket;
public static OutputStream os;
public static InputStream is;
public static ObjectInputStream ois;
public static ObjectOutputStream oos;
/* Panels & Frames */
public static JFrame mainFrame;
public static JPanel menuPanel;
public static JPanel mainPane;
/* Ohter */
public static boolean isHost = true; // is this instance a host or not?
public final static int DISCONNECTED = 0;
public final static int CONNECTING = 1;
public final static int CONNECTED = 2;
public static int connectionStatus = CONNECTING;
public static void initGUI(){
menuPanel = new JPanel();
//menuPanel = getMenu(); // some menu items
scribblePanel = new JPanel(new BorderLayout());
myCanvas = new ScribbleCanvas();
scribblePanel.add(myCanvas);
mainPane = new JPanel(new BorderLayout());
mainPane.add(menuPanel, BorderLayout.WEST);
mainPane.add(scribblePanel, BorderLayout.CENTER);
mainFrame = new JFrame("Pictionary");
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setBounds(200, 200, 800, 500);
mainFrame.setContentPane(mainPane);
mainFrame.setVisible(true);
}
public static void main(String[] args) {
initGUI();
while(true){
switch(connectionStatus){
case DISCONNECTED:
break;
case CONNECTING:
try{
if(isHost){ // You are a host
hostServer = new ServerSocket(5454);
socket = hostServer.accept();
}else{ // You're not a host
socket = new Socket("localhost", 5454);
}
os = socket.getOutputStream();
oos = new ObjectOutputStream(os);
is = socket.getInputStream();
ois = new ObjectInputStream(is);
oos.flush();
connectionStatus = CONNECTED;
}catch(IOException e){
connectionStatus = DISCONNECTED;
}
break;
case CONNECTED:
if(isHost){
try {
oos.writeObject(scribblePanel);
//oos.writeObject(myCanvas);
} catch (IOException e) {
e.printStackTrace();
}
}else{
try {
scribblePanel = (JPanel) ois.readObject();
//myCanvas = (ScribbleCanvas) ois.readObject();
mainFrame.repaint();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
break;
}
}
}
}
这是该程序的精简版本,但是可以工作。如果使用
isHost = true;
运行一次,并且使用isHost = false;
运行一次,则它们具有连接,但是随后出现以下错误:java.io.NotSerializableException: scribble3.ScribbleCanvasListener
,同时发送JPanel
和ScribbleCanvas
。java.io.NotSerializableException: scribble3.ScribbleCanvasListener
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.writeObject(Unknown Source)
at domain.Main.main(Main.java:102)
第102行引用
oos.writeObject(myCanvas)
或oos.writeObject(myScribble)
。 最佳答案
当它尝试写入一些字段时,会发生此问题。 ScribbleCanvas
的字段之一不可序列化。
我已经查看了所有字段,并且注意到哪个字段包含不可序列化的对象。是听众。您需要使侦听器类可序列化。