简体   繁体   English

Java套接字-管道破裂错误

[英]Java Socket - Broken pipe error

I am trying to send int value, long value, long array and 2d double array via socket from the Client to the Server. 我正在尝试通过套接字从客户端向服务器发送int值, long值, long数组和2d double数组。

I successfully sent int, long values and long array, however when it comes to the double array (output.writeObject(server_ind); - see Client Side code below), I am getting the following error: 我成功发送了int,long值和long数组,但是当涉及到double数组(output.writeObject(server_ind);-参见下面的客户端代码)时,出现以下错误:

ERROR: 错误:

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)

My code is the following: 我的代码如下:

Client Side: 客户端:

        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();

Server Side: 服务器端:

    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");

Thanks! 谢谢!

The Broken pipe Exception happen when the connection between sender and receiver is closed by reciver (in this case the Server Side) before the sender finish to send all the stream. 当发送者和接收者之间的连接在发送者完成发送所有流之前被接收器(在本例中为服务器端)关闭时,发生断开Broken pipe Exception

Checking your code i notice that: 检查您的代码,我注意到:

In the first case, you are sending and object of 32 bits ( int ): 在第一种情况下,您要发送和接收32位( int )的对象:

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

And wait for 32 bits: 并等待32位:

num_doc = input.readInt();

The same for the second case, when you send and recived 64 bits ( long type) 当您发送和接收64位( long型)时,第二种情况相同

In the case of an long[] you are sending an Object wich its size depends of the amount and type of the data, according whith oracle documentation, for `ObjectOutputStream: 对于long[]您正在发送一个对象,其大小取决于oracle文档中针对ObjectOutputStream的数据量和数据类型:

Write the specified object to the ObjectOutputStream. 将指定的对象写入ObjectOutputStream。 The class of the object, the signature of the class, and the values of the non-transient and non-static fields of the class and all of its supertypes are written 写入对象的类,类的签名以及该类及其所有超类型的非瞬态和非静态字段的值

But in the case of double[][] , you are sending an ( double[] ) that each element has another double[] . 但是对于double[][] ,您要发送的是( double[] ),每个元素都有另一个double[] For some reason, that is not clear for me, the ObjectInputStream is not able to read all the objects that had been sended by your client. 由于某些原因,这对我来说还不清楚, ObjectInputStream无法读取客户端发送的所有对象。

So, it could be that the receiver doesn't know how many byte need to read to build the double array. 因此,接收器可能不知道要读取多少字节才能构建双精度数组。

One question for you (@Liutauras94): Is there a exception in the server side? 您的一个问题(@ Liutauras94):服务器端是否有异常?

I recomend you to convert the double value to an array of 4 bytes (64 bits) and send it with a method write(byte[]) instead of writeObject. 我建议您将double值转换为4个字节(64位)的数组,并使用方法write(byte [])而不是writeObject发送它。 Be aweare of the order of byte that recive the other part. 厌倦了其他部分的字节顺序。

Also, in Java, there are another kind of stream writers that handle numeric data types, they are better than try to send an object. 另外,在Java中,还有另一种处理数字数据类型的流编写器,它们比尝试发送对象更好。

You're writing objects but reading primitives. 您正在编写对象,但正在读取基元。 So eventually you read less data than is really there, not to mention entirely wrong data; 因此,最终您读取的数据少于那里的实际数据,更不用说完全错误的数据了。 then you close the socket while there is still unread pending data in it; 然后在套接字中仍有未读的挂起数据时关闭套接字; and that causes a connection reset to be propagated to the writer; 并导致连接重置传播到编写器; which causes the 'broken pipe'. 这会导致“管道破裂”。

If you write data with writeObject() you must read it with readObject() . 如果使用writeObject()写入数据,则必须使用readObject()读取数据。 If you write data with writeInt() you must read it with readInt() . 如果使用writeInt()写入数据,则必须使用readInt()读取数据。 And so on. 等等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM