Java Socket - 管道错误

时间:2017-02-08 13:58:07

标签: java sockets serialization serversocket

我正在尝试通过套接字发送 int 值, long 值, long 数组和 2d double 数组从客户端到服务器。

我成功发送了int,long值和long数组,但是当涉及到double数组(output.writeObject(server_ind); - 请参阅下面的Client Side代码)时,我收到以下错误:

错误:

java.net.SocketException: Broken pipe
    at java.net.SocketOutputStream.socketWrite0(Native Method)
    at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:113)
    at java.net.SocketOutputStream.write(SocketOutputStream.java:159)
    at java.io.ObjectOutputStream$BlockDataOutputStream.drain(ObjectOutputStream.java:1876)
    at java.io.ObjectOutputStream$BlockDataOutputStream.writeByte(ObjectOutputStream.java:1914)
    at java.io.ObjectOutputStream.writeFatalException(ObjectOutputStream.java:1575)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:350)
    at clientSide.ClientSocket.connectionProtocol(ClientSocket.java:36)
    at clientSide.clientMain.main(clientMain.java:97)

我的代码如下:

客户端:

        ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());

        output.writeObject(num_doc); //int value
        output.flush();

        output.writeObject(num); //long value
        output.flush();

        output.writeObject(queryTDs); //long[] array
        output.flush();

        output.writeObject(server_ind); //double[][]
        output.flush();

服务器端:

    input = new ObjectInputStream(clientSocket.getInputStream());

    num_doc = input.readInt();
    num = input.readLong();
    TDs = (long[]) input.readObject();
    server_ind = (double[][]) input.readObject();

    output = new ObjectOutputStream(clientSocket.getOutputStream());
    output.writeObject("Received");

谢谢!

3 个答案:

答案 0 :(得分:1)

发件人完成发送所有流之前,发件人和收件人之间的连接由reciver(在本例中为服务器端)关闭时发生Broken pipe Exception

检查您的代码我注意到:

在第一种情况下,您发送的是32位(int)的对象:

output.writeObject(num_doc); //int value output.flush();

等待32位:

num_doc = input.readInt();

第二种情况相同,当您发送和接收64位(long类型)时

long[]的情况下,你发送一个对象,它的大小取决于数据的数量和类型,根据oracle文档,对于`ObjectOutputStream:

  

将指定的对象写入ObjectOutputStream。该类的对象,类的签名,以及该类的非瞬态和非静态字段及其所有超类型的值都是写的

但是在double[][]的情况下,您发送的是一个(double[]),每个元素都有另一个double[]。由于某些原因,我不清楚,ObjectInputStream无法读取客户端发出的所有对象。

因此,可能是接收器不知道需要读取多少字节来构建双数组。

一个问题(@ Liutauras94):服务器端是否有异常?

答案 1 :(得分:0)

我建议你将double值转换为4字节(64位)的数组,并使用方法write(byte [])而不是writeObject发送它。回想起其他部分的字节顺序。

此外,在Java中,还有另一种处理数字数据类型的流编写器,它们比尝试发送对象更好。

答案 2 :(得分:0)

您正在编写对象但正在阅读基元。因此,最终您读取的数据少于实际数据,更不用说完全错误的数据;然后你关闭套接字,同时还有未读的未决数据;这会导致连接重置传播到编写器;这导致'破管'。

如果您使用writeObject()撰写数据,则必须使用readObject()阅读。如果您使用writeInt()撰写数据,则必须使用readInt()进行阅读。等等。