Java - 使用 ObjectStream 发送套接字

Posted

技术标签:

【中文标题】Java - 使用 ObjectStream 发送套接字【英文标题】:Java - Send socket using ObjectStream 【发布时间】:2021-11-19 20:40:21 【问题描述】:

我有一个套接字,我想从客户端发送到服务器(或反向)。

java.net.Socket 属于 java.lang.Object 时,为什么不能使用 ObjectStream 完成?我怎样才能正确地做到这一点?

这是Server.java

package com.company;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class Server 
    public static void main(String[] args) throws IOException, ClassNotFoundException 
        ServerSocket ss = new ServerSocket(1234);       // make server on localhost:1234
        Socket socket = ss.accept();

        System.out.println("Connection from " + socket + "!\n");

        InputStream inputStream = socket.getInputStream();
        ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);

        Socket receivedSocket = (Socket) objectInputStream.readObject();
        System.out.println(receivedSocket);

        ss.close();
        socket.close();
    

这是Client.java

package com.company;

import java.io.*;
import java.net.Socket;

public class Client 

    public static void main(String[] args) throws IOException 
        Socket socket = new Socket("localhost", 1234); // make socket on localhost:1234

        OutputStream outputStream = socket.getOutputStream();
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);

        objectOutputStream.writeObject(socket);     // send `socket` over network

        socket.close();
    

Client 方面,它向我抛出了这个异常:

Exception in thread "main" java.io.NotSerializableException: java.net.Socket
    at java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1192)
    at java.base/java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:352)
    at com.company.Client.main(Client.java:14)

这在Server 方面:

Exception in thread "main" java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: java.net.Socket
    at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1696)
    at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:495)
    at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:453)
    at com.company.Server.main(Server.java:17)
Caused by: java.io.NotSerializableException: java.net.Socket
    at java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1192)
    at java.base/java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:352)
    at com.company.Client.main(Client.java:14)

提前致谢!

【问题讨论】:

不,你不能。这没有意义。可以传真传真机吗? 您能否分享更多有关您尝试使用此功能实现的目标的信息?这可能是任何人都能够帮助您的唯一方法。 请澄清您的具体问题或提供其他详细信息以准确突出您的需求。正如目前所写的那样,很难准确地说出你在问什么。 【参考方案1】:

您只能编写实现java.io.Serializable 接口的对象。您可以创建一个包含来自 Socket 的信息的配置类:

public class SocketConfiguration implements Serializable 
    
    private final String host;
    private final int port;

    public SocketConfiguration(String host, int port) 
        this.host = host;
        this.port = port;
    

    public String getHost() 
        return host;
    

    public int getPort() 
        return port;
    

尽管上面的示例毫无意义,因为您已经知道所有这些信息。您还可以创建一个扩展 java.net.Socket 并实现 java.io.Serializable 的类,但我真的不明白这样做的意义。

【讨论】:

不幸的是,这对我没有帮助。不管怎样,我很感谢你的帮助,谢谢你。 @pingupingu 你想达到什么目的?如果您必须通过对象输出流编写套接字,那么您可以创建一个扩展套接字并实现可序列化的类。 @StanvanderBend 不,你不能。所有将被序列化的将是子类的属性。不是不可序列化的Socket 类的属性,例如套接字描述符或其任何其他状态。在任何情况下,这个概念都没有意义。

以上是关于Java - 使用 ObjectStream 发送套接字的主要内容,如果未能解决你的问题,请参考以下文章

021.12 IO流 ObjectStream对象序列化

ObjectStream 及 序列化 介绍

使用XStream是实现XML与Java对象的转换--Object Stream

ObjectOutputStream:对象的序列化流

ObjectOutputStream:对象的序列化流

Java踩坑笔记:ObjectIOStream与IOStream的各种装饰器(先挖个坑,以后再来详细填)