Reading from a Socket InputStream | Telit Cinterion IoT Developer Community
March 6, 2017 - 2:57pm, 3245 views
Hello,
I have a question about data reading with InputStream when using SocketConnection.
Now, in my project, I'm reading 1 byte data at each cycle using InputStream.read() method after checking data availablity with available() method. If stream started and data not available for some time, say 100 ms, I suppose data end is reached and decide it to be a complete packet. But I this method does not seem proper and I don't want to read 1 byte at each cycle.
How can it be done more properly?
Are TCP/UDP packets written to buffer as a whole or partially at low level? When I checked the data in buffer with available() method, if there is data , can I assume it is a complete, whole TCP/UDP data packet? If it is a whole packet, I can read it to a byte array completely at one cycle.
Best Regards,
Ergün.
Hello,
You don't need to read byte by byte, you can check for data availability with available() method in each cycle and then read a certain amount of data to the buffer if data is available.
TCP packets are driven by lower layers and you have no control on this on the application layer - you just get a stream of data. In fact it should not make any difference as on the application layer you probably operate on the application layer protocol and it should not matter how this data is fragmented and defragmented on the lower layers.
In case of UDP you can read each datagram separately.
Best regards,
Bartłomiej
Hello Bartlomiej,
Thanks for the answer.
I made a test today after your explanation. I have changed the TCP receive method as below instead of reading byte by byte.
int numberOfBytesToRead = socketInStream.available();
if(numberOfBytesToRead > 0) {
System.out.println("numberOfBytesToRead in socket receive buffer : " + numberOfBytesToRead);
byte[] messageFromTCPClient = new byte[numberOfBytesToRead];
int readByteNumber = socketInStream.read(messageFromTCPClient);
System.out.println("readByteNumber: " + readByteNumber);
//Then pass TCP message to application level code, protocol.
}
The variables numberOfBytesToRead and readByteNumber in above code was printed to debug output as equal, same values. And I have checked data length which I have sent from tcp client to module. It is also equal to above values. I understand from this result that tcp data is written to inputstream receive buffer as a whole, complete data and I can read all of them at one cycle with "read( byte[] b)" method.In test, maximum length of my data from client was 76 byte. Maybe, if client data length is greater, it can be fragmented into 2 or more parts at low level. As you said, in case of fragmantation, application level can combine the fragmented parts.
Then, at this moment, I will assume, tcp low layer implementation will write the data to inputstream buffer in a meaningful size and I can pass the data which I read at one cycle to application level protocol immediately without waiting remaining parts.
Best Regards,
Thanks for additional clarifications.
So I understand that for now we close this.
Best regards,
Bartłomiej
Hello Bartlomiej,
Yes, it is more clear and seems ok at the moment.
Best Regards,