0
votes

I'm having an issue. I'm working on a simple multithread TCP server in Java, and I currently have this problem:

Client can send me an input string, such as

[IDENTIFIER] text\r\n

which is okay and I have that done. Every input query needs to be ended by a \r\n, except for one case.

This case is when a client send an image as a binary data. This message has following structure:

PHOTO[space][length of data][space][data][4 bytes of checksum in BIG ENDIAN]

and the whole point is to either return a

202 OKAY\r\n

message when checksum matches the sum of bits in data, or ...

302 BAD CHECKSUM\r\n

... otherwise. However, I'm having some serious issues with reading the 4 bytes. The input source is an instance of InputStreamReader, acquired from:

in = new InputStreamReader(this.clientSocket.getInputStream());

and function InputStreamReader.read() return an int of a char that has been just read. Now, I tried to

            correctChecksumBytes = new byte[4];
            for( int i  = 0 ; i < 4 ; ++i ) {
                correctChecksumBytes[i] = (byte) in.read();
            }

            if (correctChecksumBytes == null)   {
                throw new BadSyntax();
            }            
            bb = ByteBuffer.wrap(correctChecksumBytes);
            bb.order(ByteOrder.BIG_ENDIAN);
            fourByteCheck = bb.getInt();

However, I now understand that casting the int returned from in.read() is wrong, since the result are off by a hige amount. I was lead to believe that usage of ByteBuffer is correct, I just dont know how to fill the byte array with correct values.

I also tried to convert the InputSreamReader into byte array, but I found out that it's not a valid way to go, since a message...

PHOTO[space][length of data][space][data][4 bytes of checksum in BIG ENDIAN][IDENTIFIER] text\r\n

...is valid and needs to be interpreted as 2 messages.

I did some tests and found out I successfuly managed to read all the data and compute the valid checksum, so the next 4 bytes in the input are the 4 bytes of checksum, which I did not manage to read yet.

Also, here's an example of a valid PHOTO message

PHOTO 8 ABCDEFGH\x00\x00\x02\x24

So I'd like to ask, how can I read these 4 bytes and convert them into int to compare with computed checksum?

Thanks a lot

1
You've got an InputStreamReader. That's a reader - you don't read bytes from a reader, you read text. It sounds to me like you should rethink your protocol a little to separate the binary data from text data more clearly. For example, it's common to have a header per "message" which contains some binary data, then a body... you'd read the body as a byte array, but then if the body itself is text, you'd construct a reader on top of it (e.g. via InputStreamReader wrapping ByteArrayInputStream). - Jon Skeet
Shouldn't TCP take care of the integrity checks and so on? - Selim

1 Answers

0
votes

InputStreamReader will read character based data. You have to write your custom InputStream and read x bytes out of it.