java客户机-服务器序列化问题

java客户机-服务器序列化问题,java,serialization,client-server,eofexception,Java,Serialization,Client Server,Eofexception,您好,我正在开发一个客户端-服务器程序,其中包含一些特殊功能,如发送私人消息、显示在线列表等。因此,我知道我必须使用序列化,首先我管理了它,但过了一段时间,我就搞砸了:)现在我花时间学习序列化。我将只分享有意义的完整部分,以防止冲突。我想知道我哪里做错了。无论如何,谢谢你的帮助。这里是服务器代码的一部分 public class Server { private ServerSocket ss; private Socket socket;

您好,我正在开发一个客户端-服务器程序,其中包含一些特殊功能,如发送私人消息、显示在线列表等。因此,我知道我必须使用序列化,首先我管理了它,但过了一段时间,我就搞砸了:)现在我花时间学习序列化。我将只分享有意义的完整部分,以防止冲突。我想知道我哪里做错了。无论如何,谢谢你的帮助。这里是服务器代码的一部分

    public class Server {

        private ServerSocket ss;
        private Socket socket;
        private Map<Socket,DataOutputStream> list = new HashMap<Socket,DataOutputStream>();
        private LinkedList<Person> client_list = new LinkedList<Person>();
        private String socketName;
        private Object lockObj = new Object();

        public Server(int port_number) throws IOException{

            create_Server(port_number);
        }

        public static void main(String[] args) throws IOException {

            int port_number=23;

            new Server(port_number);
        }

        private void create_Server(int port_number) throws IOException{

            ss = new ServerSocket(port_number);

            System.out.println("Server is ready!");

            while(true){

                socket=ss.accept();

                System.out.println(socket.getLocalAddress().getHostName() + " was connected!");

                send_con_mes();

                list.put(socket,new DataOutputStream(socket.getOutputStream()) );

                ServerThread st = new ServerThread(socket,this);

                Person per = new Person(socket.getInetAddress().toString());

                client_list.add(per);

                st.start();


            }

        }

            public LinkedList<Person> send_list(){  

                   return client_list;
        }
在这里,private
ObjectInputStream socketIn获取可序列化对象并写入文件。以下是我面临的一些错误

java.io.EOFException
    at java.io.DataInputStream.readUnsignedShort(Unknown Source)
    at java.io.DataInputStream.readUTF(Unknown Source)
    at java.io.DataInputStream.readUTF(Unknown Source)
    at ServerThread.run(ServerThread.java:58)


SEVERE: null
java.io.StreamCorruptedException: invalid type code: 00
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.readObject(Unknown Source)
    at Client.read_list(Client.java:81)
    at Client.run(Client.java:61)
    at java.lang.Thread.run(Unknown Source)

所以我很感激你能帮我处理这个问题

看起来您正在使用流和同一流的装饰版本。因为有一些缓冲正在进行,所以这不起作用。坚持只使用一个装饰过的实例。

只发送您自己的对象。比如说

interface ServerToClientPacket { 
    void performAction(Client c); 
}

class MyMessage implements ServerToClientPacket {
    String message;
    MyMessage(String message) { this.message = message; }
    void performAction(Client c) {
        JOptionPane.showMessageDialog(message);
    }
}

class PersonList implements ServerToClientPacket {
    LinkedList<Person> people;
    // constructor here
    void performAction(Client c) {
        for(Person person : people) {
            c.pts.println(person);
        }
    }
}
接口服务器到客户端包{
无效履行(客户c);
}
类MyMessage实现ServerToClient包{
字符串消息;
MyMessage(字符串消息){this.message=message;}
无效执行(客户c){
JOptionPane.showMessageDialog(消息);
}
}
类PersonList实现ServerToClient包{
社交人士;
//这里是构造器
无效执行(客户c){
用于(人:人){
c、 临时秘书处println(个人);
}
}
}

每个人都将使用序列化的数据在客户机上实现自己的性能。定义行为时,不要将其放入客户端,而是将其放入消息中。然后,您的客户机就变成了一个显示机制,用于显示从套接字传递给它的各种消息和行为。

您假设“必须使用序列化”。序列化当然是这里的一个选项,但肯定不是唯一的选项

序列化有两个缺点:

  • 特定于Java的
  • 复杂序列化是Java语言更高级的特性之一
  • 重构很棘手(如果不能始终同时升级客户端和服务器,那么对同样序列化的类进行更改可能会很棘手)
  • 难以调试(如果出现问题,您无法手动检查“线外”发生的情况并查看其是否正确)
使用另一种为客户机-服务器通信而设计的编码(想到JSON)可能值得考虑


当你问一个问题“我怎么用X做FO”,人们会用“不要用X,用Y!”,但看起来你可能想考虑这个……

那么,怎样才能使用一个经过修饰的流来承载消息和对象呢?我怎样才能意识到传入的数据是一个对象或消息呢?@user743989为什么不让消息也成为流中的对象呢?只接受对象,无论它们是消息对象、行为对象还是其他任何对象。好的,那么我如何实现对象类型。例如,如果它是字符串对象或
Person
对象,或者它可能是包含对象
Person
\的链接列表?。对于这些麻烦的问题,我很抱歉,但我对java也是新手:)将
socket
声明为类变量并仅将其用作方法的局部变量有点难看。如果您能更清楚地解释您的想法,我将很高兴:)当然。我将
套接字
移动到
中,同时
创建\u服务器
中循环。这将防止任何东西干扰套接字对象,并更可靠地保护它。您永远不想不必要地公开信息。好的,我理解这个问题:)。而且要解决它…好的,这种方法更容易理解和使用。我将尝试这个想法,并在我的工作上再次设计。所以谢谢你的帮助,伙计:)是的,你是对的,但我想使用序列化,因为我想更清楚地学习这个主题,我告诉你,我也是java网络的新手。另外,伙计,不,这对我来说并不烦人:)。另一方面,我只想用简单的java:D来完成这项工作,所以学习JSON对我来说是强制性的:)。但无论如何,谢谢你的建议
java.io.EOFException
    at java.io.DataInputStream.readUnsignedShort(Unknown Source)
    at java.io.DataInputStream.readUTF(Unknown Source)
    at java.io.DataInputStream.readUTF(Unknown Source)
    at ServerThread.run(ServerThread.java:58)


SEVERE: null
java.io.StreamCorruptedException: invalid type code: 00
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.readObject(Unknown Source)
    at Client.read_list(Client.java:81)
    at Client.run(Client.java:61)
    at java.lang.Thread.run(Unknown Source)
interface ServerToClientPacket { 
    void performAction(Client c); 
}

class MyMessage implements ServerToClientPacket {
    String message;
    MyMessage(String message) { this.message = message; }
    void performAction(Client c) {
        JOptionPane.showMessageDialog(message);
    }
}

class PersonList implements ServerToClientPacket {
    LinkedList<Person> people;
    // constructor here
    void performAction(Client c) {
        for(Person person : people) {
            c.pts.println(person);
        }
    }
}