InputStream не получает EOF - PullRequest
3 голосов
/ 02 октября 2011

Я пытаюсь отправить изображение с моего устройства Android на мой компьютер через сокет. Проблема в том, что входной поток на моем компьютере читает каждый байт, кроме последнего набора. Я попытался обрезать байтовый массив и отправить его, я вручную выписал -1 в выходной поток несколько раз, но входной поток никогда не читает -1. Просто висит в ожидании данных. Я также пытался не закрывать поток или сокеты, чтобы посмотреть, была ли это какая-то проблема с синхронизацией, но это также не сработало.

Клиентская часть (телефон Android)

//This has to be an objectoutput stream because I write objects to it first
InputStream is = An image's input stream android
ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
objectOutputStream.writeObject(object);
objectOutputStream.flush();

byte[] b = new byte[socket.getSendBufferSize()];
int read = 0;
while ((read = is.read(b)) != -1) {
   objectOutputStream.write(b, 0, read);
   objectOutputStream.flush();
   b = new byte[socket.getSendBufferSize()];
}
//Tried manually writing -1 and flushing here
objectOutputStream.close();
is.close();
socket.close();

Сторона сервера (компьютер) Этот бит кода происходит после того, как входной поток объекта считывает отправленные объекты. Он только начинает читать, когда файл начинает отправлять

File loc = Location of where the file is stored on the computer
loc.createNewFile();
FileOutputStream os = new FileOutputStream(loc);
Socket gSocket = The socket
ObjectInputStream gInputStream = Object Input stream created from the sockets input stream already used to read in the previous objects

byte[] b = new byte[gSocket.getReceiveBufferSize()];
int read = 0;
while ((read = gInputStream.read(b)) != -1) {
   os.write(b, 0, read);
   os.flush();
   b = new byte[gSocket.getReceiveBufferSize()];
}

os.close();

Этот код никогда не читает -1, даже если я пишу -1 напрямую и очищаю поток. Результатом является java.net.SocketException: сброс соединения при закрытии потока или сокета с устройства Android. Изображение почти полностью отправлено, но самые последние пиксели изображения серые. Я также даже попытался использовать поток out / input напрямую из сокета вместо уже созданного objectinputstream / objectoutputstream, и он все еще не работает.

Ответы [ 3 ]

8 голосов
/ 02 октября 2011

Во-первых, я думаю, вы неправильно поняли значение EOF (-1). Это не означает, что сервер записал -1, это означает, что сервер закрыл поток.

Я думаю, что ваша основная проблема заключается в том, что и сервер, и клиент читают в цикле, и ни один из них не достигает точки, где они закрывают поток. Они зашли в тупик - оба ждут, пока другой закроется первым.

Ваш клиент:

Your client

Ваш сервер:

Your server

Если вы знаете, что у вас больше нет данных для записи, просто закройте поток.

3 голосов
/ 02 октября 2011

Поскольку вы уже используете ObjectInputStream и ObjectOutputStream, вы можете использовать их соответствующие методы readObject и writeObject для чтения / записи целых объектов одновременно. Может быть, вы могли бы отправить / получить весь байтовый массив как объект?

На вашем андроиде:

1) byte [] imageBytes = ...; // содержит изображение

2) objectOutputStream.writeObject (imageBytes);

На вашем компьютере:

1) byte [] imageBytes = (byte []) readObject ();

2) получить изображение из imageBytes

Конечно, вам придется использовать readObject из потока, так как он будет блокироваться.

1 голос
/ 02 октября 2011

Вы пишете байтовые массивы [] как объекты, но читаете байты. Вы должны читать объекты и приводить их к byte []. EOS вызовет исключение EOFException.

...