Java 如何通过套接字发送非常大的对象

Java 如何通过套接字发送非常大的对象,java,sockets,large-data,Java,Sockets,Large Data,我的系统涉及通过TCP套接字发送大量数据和元数据。我正在发送一个包含各种元数据以及20字节数组的对象。到目前为止,我一直在使用包含BufferedOutputStream的ObjectOutputStream编写小示例(130kB数组)。我试图达到67MB阵列的目标,但ObjectOutputStream无法处理那么多数据。我能够发送1MB数组,但writeObject()在2MB时挂断 我听说DataOutputStream速度更快,但我不希望将元数据编码为字节并在另一端解码。有没有一种能够快

我的系统涉及通过TCP套接字发送大量数据和元数据。我正在发送一个包含各种元数据以及20字节数组的对象。到目前为止,我一直在使用包含BufferedOutputStream的ObjectOutputStream编写小示例(130kB数组)。我试图达到67MB阵列的目标,但ObjectOutputStream无法处理那么多数据。我能够发送1MB数组,但writeObject()在2MB时挂断

我听说DataOutputStream速度更快,但我不希望将元数据编码为字节并在另一端解码。有没有一种能够快速发送非常大的对象的好方法

编辑:

我已经在每个写入方法之后使用reset()。我目前正在发送一个SignedObject,其中包含我自己的Message对象,该对象包含20个数组以及许多元数据字段。我更愿意把这一切打包,因为它是如此方便,但我明白,分离可能是唯一的出路。尽管如此,我仍然需要确保所有传输都是安全的

更新:

所以我去吃午饭,回来后,决定试着弄清楚发送端还是接收端的事情是否悬而未决。然后它就再也没有挂断。我可以继续成功地发送多达4MB的阵列,直到堆用完(这与堆无关,只是意味着我需要一台更好的计算机或更高效的处理)。所以我猜问题消失了?但这并不意味着我不需要更好的方式来传递信息,所以如果人们有想法,我会采纳更多的想法。另外,我假设一旦我更新这个,它将再次停止工作

有没有一种能够快速发送非常大的对象的好方法

在发送的对象之间使用ObjectOutputStream和reset()。除非你只有几MB的内存(你应该得到更多),否则你不会有问题

与自己编码字节相比,ObjectOutputStream速度非常慢,但它可以很好地处理编码。更有可能的是,你的网络上传速度是你的限制因素。在本例中,它发送速度约为600 Mb/s,而大多数braodband连接速度约为500 kb/s(大约慢1000倍)


使用量子物理立即感知它?:-)或者用一种枯燥的方式:压缩你真的希望60MB的数据能立即传输吗?不管你怎么做(除非你能压缩或消除它的大部分),它都会相对缓慢。这就是为什么我们没有从互联网上启动的电脑的部分原因,因为它“太慢”了,会无限期地挂起。为澄清而编辑如果您的代码挂起,那么您有一个bug。我已经使用ObjectOutputStream发送GB的数据,其中包含一个问题。虽然协议可能有点冗长,但它不会挂起。至于详细程度,如果发送大量数据,我怀疑OOS开销是否重要。@jtahlborn:如果挂起,那么问题是否会出现在接收端?听起来OP发送的是一个大对象,因此重置在这种情况下可能不可用。@jtahlborn OP说2 MB对象失败。很难看出仅仅2MB怎么会太多。要引起一个问题就得有几百个。
ServerSocket ss = new ServerSocket(0);
Socket s = new Socket("localhost", ss.getLocalPort());
final Socket s2 = ss.accept();
ss.close();

new Thread(new Runnable() {
    @Override
    public void run() {
        int count = 0;
        long start = System.nanoTime();
        try {
            ObjectInputStream in = new ObjectInputStream(
                    new InflaterInputStream(s2.getInputStream()));
            while (in.readObject() != null) count++;
            s2.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        long time = System.nanoTime() - start;
        System.out.printf("Read %,d objects in %.3f seconds%n", count, time / 1e9);
    }
}, "reader").start();
ObjectOutputStream oos = new ObjectOutputStream(
        new DeflaterOutputStream(s.getOutputStream()));
for (int i = 0; i < 20; i++) {
    byte[] bytes = new byte[67 * 1000 * 1000];
    oos.writeObject(bytes);
    oos.reset();
}
oos.writeObject(null); // poison pill
oos.close();
s.close();
Read 20 objects in 21.644 seconds