2017-02-08 16 views
0

Я пытаюсь отправить INT значения, долгого значения, длинного массива и 2d двойных массива через сокет от клиента к серверу.Java Socket - Разбитая ошибка трубы

Я успешно отправлены Int, длинные значения и длинный массив, однако, когда речь идет о двойном массиве (output.writeObject (server_ind) - см на сторону клиента коды ниже), я получаю следующее сообщение об ошибке:

ОШИБКА:

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) 

Мой код выглядит следующим образом:

стороне клиента:

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

Сервер:

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

Спасибо!

+0

Вы могли бы показать осмысленный код? Исключение составляет: clientSide.ClientSocket.connectionProtocol (ClientSocket.java:36) Но не находится в сообщении – efekctive

+0

Как описано выше - «однако, когда дело доходит до двойного массива (output.writeObject (server_ind); код ниже) ", поэтому output.writeObject (server_ind); то есть 36-я строка, которая содержится в коде, извиниться, если ее недостаточно ясно. – Liutauras94

+0

Что такое серверные журналы? Я предполагаю, что где-то рядом с строкой 'TDs = (long []) input.readObject();' исключение вашего кода. – user1516873

ответ

0

Я рекомендую вам преобразовать двойное значение в массив из 4 байтов (64 бит) и отправить его методом write (byte []) вместо writeObject. Будьте осторожны с порядком байта, который возвращает другую часть.

Кроме того, на Java существует другой тип потоковых писателей, которые обрабатывают числовые типы данных, они лучше, чем пытаться отправить объект.

+0

Вы рекомендуете его почему? – EJP

+0

Потому что проще выполнить отладку на низком уровне, чтобы узнать, какая информация отправляется сокетом, а поток данных вы можете распечатать и проанализировать порядок байтов, который отложен, также вы можете создать журнал, который имеет необработанные данные в шестнадцатеричном формате информации, которая будет получена, эта информация полезна при создании сервера и клиентов на разных платформах, таких как Java и .Net. Именно по этой причине я рекомендую его. –

+0

Итак, вся эта информация должна появляться в вашем ответе, вместо того, чтобы ее просить, но нет ничего, что бы определило, почему OP получил ошибку «сломанного трубопровода». И это не мультиплатформенный вопрос: речь идет о Java Serialization. – EJP

0

Вы пишете объекты, но читаете примитивы. Поэтому в конечном итоге вы читаете меньше данных, чем на самом деле, не говоря уже о совершенно неправильных данных; то вы закрываете сокет, пока в нем еще нет непрочитанных ожидающих данных; и это приводит к тому, что сброс соединения будет передаваться автору; который вызывает «сломанную трубу».

Если вы пишете данные с помощью writeObject(), вы должны прочитать его с помощью readObject(). Если вы пишете данные с writeInt(), вы должны прочитать его с помощью readInt(). И так далее.

1

Broken pipe Exception происходит, когда соединение между отправителем и приемником закрыто ресивером (в данном случае стороной с сервером) до завершения отправления для отправки всего потока.

Проверка кода я замечаю, что:

В первом случае, вы отправляете и объект 32 бит (int):

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

И ждать 32 бит:

num_doc = input.readInt();

То же самое для второго случая, когда вы отправляете и получаете 64 b его (long тип)

В случае long[] вы отправляете объект Wich его размер зависит от количества и типа данных, согласно ти оракула документации для `ObjectOutputStream:

Write the specified object to the 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

Но в случае double[][], вы отправляете (double[]), что каждый элемент имеет еще один double[]. По какой-то причине это не ясно для меня, ObjectInputStream не может прочитать все объекты, которые были отправлены вашим клиентом.

Таким образом, может случиться так, что получатель не знает, сколько байтов необходимо прочитать для создания двойного массива.

Один вопрос для вас (@ Liutauras94): Есть ли исключения на стороне сервера?

+0

спасибо за ваш ответ, это была именно моя проблема. Я отправлял объект, но ожидал и int. :) – Liutauras94