如何在套接字通道中发送和接收序列化对象

Posted

技术标签:

【中文标题】如何在套接字通道中发送和接收序列化对象【英文标题】:How to send and receive serialized object in socket channel 【发布时间】:2010-11-29 23:54:11 【问题描述】:

我想通过套接字通道传输序列化对象。 我想将“嗨朋友”字符串作为序列化对象,然后将此对象写入套接字通道,而在另一端我想读取相同的对象并检索数据。

我想使用 Java SocketChannel 完成所有这些事情。这个怎么做? 我已经尝试如下,但在接收方没有得到任何数据。

private static void writeObject(Object obj, SelectionKey selectionKey) 
    ObjectOutputStream oos;
    try 
        SocketChannel channel = (SocketChannel) selectionKey.channel();
        oos = new ObjectOutputStream(Channels.newOutputStream(channel));

        oos.writeObject(obj);
     catch (IOException ex) 
        ex.printStackTrace();
    


private static Object readObject(SelectionKey selectionKey) 
    ObjectInputStream ois;
    Object obj = new Object();
    SocketChannel channel = (SocketChannel) selectionKey.channel();
    try 
        ois = new ObjectInputStream(Channels.newInputStream(channel));
        obj = ois.readObject();
     catch (Exception ex) 
        ex.printStackTrace();
    
    return obj;

【问题讨论】:

问题不见了! 你的 SocketChannel 已经打开并连接了吗? 是的套接字通道已打开并已连接 【参考方案1】:

您的 SocketChannel 处理似乎不完整,请参阅这个 complete SocketChannels 传输字节的示例:

/*
 * Writer
 */
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.InetSocketAddress;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;

public class Sender 
    public static void main(String[] args) throws IOException 
        System.out.println("Sender Start");

        ServerSocketChannel ssChannel = ServerSocketChannel.open();
        ssChannel.configureBlocking(true);
        int port = 12345;
        ssChannel.socket().bind(new InetSocketAddress(port));

        String obj ="testtext";
        while (true) 
            SocketChannel sChannel = ssChannel.accept();

            ObjectOutputStream  oos = new 
                      ObjectOutputStream(sChannel.socket().getOutputStream());
            oos.writeObject(obj);
            oos.close();

            System.out.println("Connection ended");
        
    

还有读者

/*
 * Reader
 */
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.InetSocketAddress;
import java.nio.channels.SocketChannel;

public class Receiver 
    public static void main(String[] args) 
    throws IOException, ClassNotFoundException 
        System.out.println("Receiver Start");

        SocketChannel sChannel = SocketChannel.open();
        sChannel.configureBlocking(true);
        if (sChannel.connect(new InetSocketAddress("localhost", 12345))) 

            ObjectInputStream ois = 
                     new ObjectInputStream(sChannel.socket().getInputStream());

            String s = (String)ois.readObject();
            System.out.println("String is: '" + s + "'");
        

        System.out.println("End Receiver");
    

当您首先启动服务器,然后是接收器时,您将获得以下输出:

服务器的控制台

Sender Start
Connection ended

接收者的控制台

Receiver Start
String is: 'testtext'
End Receiver

这不是最好的解决方案,但遵循您使用Java的ServerSocketChannel

【讨论】:

“不是最佳解决方案”是什么意思。你能详细说明一下吗?另外,如果你在一个通道周围包裹一个流,你会失去 NIO 的性能吗?谢谢! 性能不是正确的词。我的意思是我尝试将上面的代码合并到我现有的“非阻塞”NIO 代码中,但我得到了“java.nio.channels.IllegalBlockingModeException”。您有解决方法或“更好的解决方案”吗? 嗨,a) 上面的代码只能阻塞。 b)我不会详细说明更好的解决方案,您将为此回答一个单独的问题。而且,总会有更好的解决方案。

以上是关于如何在套接字通道中发送和接收序列化对象的主要内容,如果未能解决你的问题,请参考以下文章

如何在java中使用套接字发送/接收对象[重复]

如何在 Python 中使用套接字创建通道

Java - 从套接字通道读取

Protobuf 多对象序列化顺序?

用于发送和接收用户定义对象的套接字程序不起作用

python3套接字发送接收'字节'对象没有属性'读取'