【问题标题】:Sorting data received through ObjectInputStream对通过 ObjectInputStream 接收的数据进行排序
【发布时间】:2013-10-28 19:55:46
【问题描述】:

我制作了一个通过 ObjectInputStream 从服务器接收数据的信使。 我希望能够检索/发送可序列化文件,同时还能够从用户那里检索/发送消息。

我找不到一种在两者(对象和消息)之间进行排序而不与消息传递冲突的好方法。

我尝试为同一个套接字(Data*Stream 和 Object*Stream)使用两个流,它似乎建立得很好,但是当我尝试通过 Data*Stream 从服务器向客户端发送消息时,我在我的客户端上获取java.net.SocketException: socket closed。 (仅在我发送消息时发生)

有人能指出我将如何通过流检索 2 种不同类型的信息的正确方向吗? (没有采取简单的出路。我不想做writeObject("[message]"+input); 或任何类似的廉价技巧。



(编辑)解决方案:

感谢 janos,他启发了我编写这段代码。 :') 谢谢哥们

输入接收器:

protected Object data;

public synchronized Object receivedData() throws ClassNotFoundException,
                                                 IOException {
    data = in.readObject();

    if(!(data instanceof String)) {
        retrieveObject();
        data = "";
        System.out.println("Object");
    }
    return data;
}

还有消息线程:

ExecutorService pool = Executors.newScheduledThreadPool(1);

private Runnable receiveData;
public void receiveData() {
    receiveData = new Runnable() {

        public void run() {
            String input;
            try {
                while((input = (String) receivedData()) != null) {
                    if(input.length() > 1) 
                        System.out.println(input);

                }
            }catch(IOException | ClassNotFoundException e){ e.printStackTrace();}
        }
    };

    pool.execute(receiveData);
}

如果您有任何改进提示,请告诉我,我会更新此代码。

【问题讨论】:

    标签: java sockets stream objectinputstream objectoutputstream


    【解决方案1】:

    您可以创建父类Message,以及子类DataMessageTextMessage

    当收到Message时,你可以用instanceof检查它的底层类型,并进行相应的处理。

    这些*Message 类可以将您想要在客户端和服务器之间传递的任何对象包装在它们的成员变量中。 *Message 类必须是可序列化的,因此所有成员变量也必须是可序列化的。

    例如给定这些Message 类型:

    class Message {}
    
    class TextMessage extends Message {
        String text;
    }
    
    class DataMessage extends Message {
        User user;
    }
    

    您可以处理收到的消息,例如:

    Message message = (Message) in.readObject();
    if (message instanceof TextMessage) {
        // do something with ((TextMessage)message).text
    } else if (message instanceof DataMessage) {
        // do something with ((DataMessage)message).user
    }
    

    【讨论】:

    • 你能举个例子吗?如果我要从服务器-> 客户端发送(比如说..)User.java,则从服务器发送的对象是用户,检索到的对象是用户。用户扩展了对象,所以我要做的就是User user = (User) in.readObject();,但是如果我使用类进行排序,那将如何工作?
    • 可能需要我一段时间来测试一下,但这似乎是合乎逻辑的。我会尝试一下,如果它有效,我会更新你。谢谢:)另外,谢谢你的例子,这就是我的想法
    • 我没有使用 Serializable 类对消息和对象进行排序,而是在它们进入时对其进行排序。起初,我认为所有通过的对象都是对象,直到你投射它,但我猜不会。感谢'instanceof'的提醒,不要用到足以让我牢牢记住它
    【解决方案2】:

    我希望能够检索/发送可序列化文件,同时还能够从用户那里检索/发送消息。

    您可以使用ObjectInputStreamObjectOutputStream 完成所有这些操作。

    我找不到一种在两者(对象和消息)之间进行排序而不与消息传递冲突的好方法。

    除非您指定“冲突”,否则该声明毫无意义。

    我尝试对同一个套接字使用两个流(Data*Stream 和 Object*Stream)

    1. 你不能这样做。在套接字的整个生命周期中使用相同的流。

    2. 您不需要这样做。你可以用Data*Stream 做的任何事情都可以用Object*Stream, 做,因为Data*Stream 实现了Data*PutObject*Stream 实现了Object*Put,并且Object*Put 扩展了Data*Put

    它似乎建立得很好,但是当我尝试通过 Data*Stream 从服务器向客户端发送消息时,我得到 java.net.SocketException: socket closed on my client。

    这意味着关闭了流并继续使用它。这是由于您使用了两个流造成的。关闭任何包裹在套接字输入或输出流周围的流会关闭另一个流和套接字。你不需要这个。

    (仅在我发送消息时发生)

    仅当您读取或写入已关闭的流时才会发生这种情况。

    有人能指出我将如何通过流检索 2 种不同类型的信息的正确方向吗?

    只需使用Object*Stream的API即可。

    (没有采取简单的方法。我不想做 writeObject("[message]"+input); 或任何类似的廉价技巧。

    我不知道你为什么认为这是一个“便宜的把戏”。您需要停止做出假设并开始设计。

    【讨论】:

    • 不必粗鲁。你在那里重复了很多次,并没有帮助我一点。我没有遇到任何冲突,因为冲突很明显。如果我以这种方式排序,那么除非我加倍努力解决错误,否则用户可能会手动导致系统混乱。
    • 这里没有粗鲁,你试图引入这种无关紧要的做法是不受欢迎的。您似乎对澄清您想要避免的“冲突”没有实际兴趣。您声称这“对[您]没有一点帮助”的说法显然是错误的。我告诉过你,你不需要同时使用这两种类型的流;我已经提供了一个严格的证据来证明为什么会这样;我还解释了为什么你遇到了异常。显然,你对争论比解决问题更感兴趣。很抱歉打扰了。
    • 1.如果“冲突与问题无关”,你为什么要提到它? 2. 如果你很明显不能在同一个底层流上使用两个流,关闭其中一个,然后在没有异常的情况下使用另一个,你为什么要这样做? 3. 我让你搜索的究竟是什么“不存在的帮助”? 3. Object*Streams API 您问题的答案。如果您要抱怨这里所提供的帮助,至少要努力保持其合理性。
    • 请把业余心理学排除在外。 java.net.SocketException: socket closed 表示关闭了它。好吗?
    • EJP,你看起来很沮丧,你好吗?无需对 stackoverflow 大发雷霆……
    猜你喜欢
    • 2013-07-13
    • 2020-07-03
    • 2014-03-05
    • 1970-01-01
    • 1970-01-01
    • 2015-10-07
    • 2022-08-18
    • 1970-01-01
    • 2017-11-09
    相关资源
    最近更新 更多