Java BufferedInputStream.read() fails - android

I am working on an android app that has continuous communication between the phone and a local server on the computer through cable and Android Open Accessory connection(AOA), the server(the computer) keeps sending packets of bytes to the android, then android parse them, all kinds of data gets received successfully.
In the implementation I am using BufferedInputStream like this:
val bufferedInputStream = BufferedInputStream(inputStream, 8192) // 8192 is the def buffer size
As I said everything works fine UNTIL android received a packet that is larger than 8192 which is the buffer size, in this case I need to loop until I read the whole packet is read(I know the size of the packets because I send that in the beginning of the packet)
When this kind of packet gets received, the call
bufferedInputStream.read(anyByteArrayOfTheWriteSize)
fails with message "Invalid argument", the annoying thing is that I can read the beginning of the packet which has the size and parse it successfully, so for example it tells android that the size of this packet is for ex 10192 bytes, this means that it needs to read 8192 then will do another iteration and read the remaining 200 bytes.
but it does not, it just fails once it reaches the call of the method read.
I was trying to use inputStream instead of bufferedInputStream but it did not work at all, bufferedInputStream kinda worked like magic, not sure why?! but this is not the topic of the question, just adding this info if incase it is needed.

Related

How remove buffer limitation in stm32 controller?

I have an stm32 microcontroller and try to connect to it in Android with a USB library. All of the things are good and can send data and receive data from stm32, but the receiving data is not complete and only receive 20 bytes from the first packet.
I do it via USB UsbEndpoint. Original packet size is 1024 bytes but receiving data are 1024 with a null value. I have read, max packet size is 64 bytes, Is that right?
PS: My main problem is in Android, because in Realterm software, data is being received completely.

Android bluetooth chunk size

I'm experiencing a strange behavior of bluetooth socket (in my opinion), and I would like know if anybody can clarify it to me.
The situation:
I have two Android applications connected together by a Bluetooth socket:
The first makes a simple write(byte[] message) on the output stream.
The second makes a simple read(byte[] buffer) on the input stream.
On the reader side I use a buffer of 1024 bytes. The sender send a message a little bit larger than the receiver buffer size: 1024 + 108 bytes (always the same message).
Ok now the behavior:
On the reader app I receive the most often a first chunk of 1024 bytes which fills up the buffer (as expected) and then a second one of 108 bytes.
But really often (maybe 40% of the time) I receive a first chunk of 1008 bytes and then a second one of 124 bytes.
I really would like to understand this because I'm affraid to miss an important bluetooth concept. At first I was thinking to compare the count of byte read with the buffer size to know if the entire message had been received but this experimentation shows that it's maybe not a good idea.
Is anybody can explain to me this behavior?
Thanks in advance.
For the record, I now use Google Guava methods for read/write on streams and all works fine.
I'm finding the same thing- it seems to be because Bluetooth sends data over as a stream instead of packets.
So if I send 4 500 byte packets, it might end up sending a 1600 byte one and a 400 byte one, or the way I sent it. Over stack overflow questions say to use some random value in the byte array to tell when a message is finished (How to read all bytes together via Bluetooth?).
There should be a better way, but I plan to use a very unlikely character set to try to find the end of the message- and pad it onto the end of each of my messages going out. Some of the other stack overflow questions suggest using '\n', but I might end up using several to make it more unlikely, such as: "\t~\t"- something that should never be typed in my game (or hopefully not extracted from the enormous amount of other stuff going on).
Hope that helps!

What is the Maximum packet size to send data over bluetooth in Android?

I'm working on an Android Bluetooth project to send and receive data from a custom made hardware. I used Bluetooth Chat Sample in SDK as basis.
I am sending data from one device to another (LG Nexus 4). All is ok until I reach a length of 1004 bytes (it is the audio data). At that point it splits it into 2 messages of 990 and 14 bytes in most of cases. but is strange sometimes its sending 1004 without splitting (approx. 4 times in 100).
I am sending this packet of 1004 bytes, in which there is 4 bytes is my header and rest of 1000 bytes is actual data which I want to use as per command in header, now if packets are splitting as per above mentioned way than I cannot handle the flow.
So, please let me know why packets are splitting in such way and how can I stop this splitting or, if I cannot do this, than please suggest me any alternative way to do this.
Thanks.
Data sent via Bluetooth socket is abstracted as a stream. Here the transport layer is broken into packets, where packet has a maximum size of almost 1KB(1000 bytes). So you can devise a mechanism in which you can send the message length info in the header, then on receiving side you will have to make subsequent read() calls; each returning data for one packet.

Much time taken in data read from socket

I'm using sockets for data transfer from one android phone and PC, I am using DataInputStream.
But it takes a long time in data transfer, about 10 minutes to transfer a 4 MB file.
Could anyone suggest any better way to do that?
I did some changes in my code and now it is taking 15 seconds to read about 1 Mb of data. I want to improve its performance.
My Code is:
InputStream is= socket.getInputStream();
DataInputStream inChannel= new DataInputStream(new BufferedInputStream(in));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int oneByte;
while ((oneByte = inChannel.read()) != -1) {
if (oneByte == 0) {
break;
}
baos.write(oneByte);
byteCount++;
}
byte[] inData = baos.toByteArray();
baos.close();
Are you sure you are not sending empty packets in between there or packets doing something else? If you are using TCP if a packet doesn't reach its destination (a buffer is overfilled with other packets somewhere in between your connection on the router or on one of the devices) the packet will have to be resent. This might be because of your setup. Given the little information you have given us, I can give the the following advice:
Look into more advanced typologies, I am going to assume you are not using any of these:
A send a receive thread; the send thread pushes out packets which you put into a queue:
|P| - packet held inside a Que part of your program
send out thread <-| P | P | P | <-App/program
reveive -> | P | P | P| P -> App/Program deques and analyses data
because your send and receive queuing system works along side each other they are constantly buffering up the received and sent packets. What seems to be happening with your setup (as far as I assume) is that you have a loop which grabs the latest packets and analyses them. This means that the hardware (part of your network hardware) buffer is overfilling with packets which your program is doing other things and by the time your program comes around to collect them, some of them are missing. This causes one side to go "I didn't get those packets, send them again", in other words, your resending the packets you should of sucked up into a Que which are waiting to be dequeued and analysed. The queue can grow regardless of how quickly the program is back to grab that data and do stuff with it (of course you are confined to the RAM). That way you ensure that you have possession of packets that you are supposed to receive rather than rely on your network card/receiver to hold on to them for you, possibly overflowing its buffer.
Another approach is to do a handshake system were one of the programs waits until the last packet is trasmitted, recieved and the other side goes "Cool, send me the next one". This slows down your download/upload speed but is a little bit quicker than packets falling off the end of the end of one of the buffers (each node, such as your router buffers your packets in case more come in than it can handle at a cycle) in the network.
You should utilize a state machine if you can on one or both ends. When your app is downloading the file, lock it into a receive state so its not trying to send/receive other stuff at the same time. Once the download is complete, switch to any other state (say, open file state). If you don't know much about state machines, I recommend you look at the wikipedia article:
http://en.wikipedia.org/wiki/Finite-state_machine

Bluetooth Inputstream Android 2.2

I'm trying to connect a bluetooth device and to read out information from it.
I've used the Bluetooth chat example and changed the UUID tp SPP mode.
The connection works, but the Information that I get from the Inputstream is wrong.
The transmitted String is 20 signs long, but the Inputstream just returns a 7. The rest of the bufferstream is empty.
Does anyone has a clue?
After write try flushing the transmitter's stream.
And on the receiver you will need to wait till you receive the expected bytes.
SPP does not have packet boundaries. So you can receive the packets in multiple chunks and you need have some logic to determine packet boundaries.

Categories

Resources