1

I have a multithreaded program java java socket and I receive the information bizare. like this ¤¤¤¤¤¤23456718900263678722¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

public void run() 
       {
            try {

                byte[] bs = new byte[64];

                 // read data into buffer
                 dataReception.read(bs);

                 // for each byte in the buffer
                 for (byte b:bs)
                 {
                    // convert byte into character
                    char c = (char)b;

                    // print the character
                    System.out.print(c);
                 }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

4 Answers4

3

The problem is here:

// read data into buffer
dataReception.read(bs);

Read doesn't read exactly that amount of bytes that you want to have in that array. It can read any number of bytes. Therefore you always have to check the return value of the read operation; and only when all expected bytes were read ... you should continue!

The reason that your output looks like garbage is this not that you would be receiving special characters.

What happens is:

  • You create a new array (which is initialized with zeros values).
  • Then you read some bytes, most likely, not enough bytes to fill that array.
  • After the first read, you print that array that now contains the initial zero values; and some bytes that resemble printable characters.

This can be verified by printing your array before reading. You will see that only contains those "special" characters.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • A new byte array is always initialised to zeros. – user207421 May 27 '15 at 11:55
  • @EJP Is that true also for local variables? See the comments on http://stackoverflow.com/questions/3426843/what-is-the-default-initialization-of-an-array-in-java – GhostCat May 27 '15 at 12:04
  • It is true for every array of primitives. 'Local variable' doesn't come into it. The array is always on the heap. Similarly, arrays of objects are always initialized to nulls. – user207421 May 27 '15 at 12:07
  • @EJP Interestingly enough; my intuition was "an array should be all 0"; but I had a shroud of cloud; so I turned to SO ... instead of running the code myself. Thanks for your correction. – GhostCat May 27 '15 at 12:33
1

If you're expecting exactly 64 byes, use readFully() instead of read(), or at least take some notice of its return value.

user207421
  • 305,947
  • 44
  • 307
  • 483
0

Try:

public void run() 
       {
            try {

                byte[] bs = new byte[64];

                 // read data into buffer
                 int readed = dataReception.read(bs);

                 // for each byte in the buffer
                 for (int n=0; n<readed;n++)

                 {
                    byte b=bs[n];

                    // convert byte into character
                    char c = (char)b;

                    // print the character
                    System.out.print(c);
                 }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
Krzysztof Cichocki
  • 6,294
  • 1
  • 16
  • 32
0

DataInputStream is usually used when textual information need to be shared over socket. Use DataInputStream.readUTF() method if the transferred data is sent using DataOutputStream.writeUTF(String str) from the other end. DataInputStream and DataOutputStream sends two byte(unsigned) length of data before sending actual data.

final String data = din.readUTF();
krishna T
  • 425
  • 4
  • 14