There is a server that sends a number of bytes on command. The amount of data is known in advance - 280 KB. Data is transmitted via a Wi-Fi network over a TCP / IP connection. It uses its own protocol, which does not display the number of transmitted information. The whole “server” feature of the server is that it opens the stream (stream) and transmits the information with frames of different sizes. The size of each frame can vary from 10 to 2048 bytes. It will transmit frames until it transfers the entire amount of data (280 KB). In other words, when receiving data on an Android device, I can’t determine the amount of data received in the stream, so I cannot place all the data in the correct form.

Question: How to properly implement data reception with such "features"?

Possible solution: I decided to try to create an array of 2048 in size (maximum possible frame size) bytes and write each new frame to this array:

DataInputStream din = new DataInputStream(socket.getInputStream()); byte[] buffer = new byte[2048]; din.read(buffer); 

Then I tried to put the data from my buffer array into the ArrayList collection, but another problem arose: how to determine where the necessary data ended, which I saved in the buffer array?

  • if the size is known, you can create an array of the desired size and call DataInputStream.readFully . In general, this is not a "server feature", but tcp works this way. - zRrr
  • The read method returns the number of bytes read into the buffer. Accordingly, this number must be stored in a variable, and then transfer such a number of bytes from the buffer where necessary. - Regent
  • @Regent is true, I didn’t notice something, that the read method still returns something. Thank! But do not tell me, how is it right in my case to deal with array processing? Each new received byte [] array leads to the form Byte [] and put into the collection or immediately create a huge array (namely byte[] array = new byte[1024 * 280] ) and put the data there? - ivanovd422
  • @ Denis422 if you know the amount of transmitted data in advance and you need all of them, then it makes sense to create one large array (like the specified array ), and then write read bytes into it in blocks. Linking lists here is a waste of memory and unnecessary inconvenience (after all, it is necessary to store its actual size for each read "piece"). So I am for new byte[1024 * 280] and System.arraycopy(buffer, 0, array, arrayPointer, readCount) . - Regent
  • @Regent thank you, you can issue as an answer - ivanovd422

1 answer 1

Since you know the amount of data transferred in advance, it makes sense to create one large array (if you need the entire data), then write the read bytes into it in blocks.

You can determine the number of bytes read into the buffer by the number returned by the read method.

Linking lists here is a waste of memory and unnecessary inconvenience (after all, it is necessary to store its actual size for each read "piece").

A schematic code for reading data in blocks and writing to the resulting array:

 public byte[] read(Socket socket) throws IOException { byte[] array = new byte[280 * 1024]; int arrayPointer = 0; DataInputStream din = new DataInputStream(socket.getInputStream()); byte[] buffer = new byte[2048]; int readCount; while ((readCount = din.read(buffer)) != -1) { System.arraycopy(buffer, 0, array, arrayPointer, readCount); arrayPointer += readCount; } return array; }