Search code examples
androidsocketsdatainputstream

socket read wrong data from dataInputStream


I want to send text and file to in my app with local Wi-Fi network I consider for any communication this format:

1 byte message mode(file or text) + long for message length + message(text or file)

this is my write code :

private void sendFile() throws JSONException {

    if (outputStream == null)
        return;
    InputStream inputFile = null;
    try {
        outputStream.writeInt(G.FILE_MODE);
        outputStream.writeLong(file.length());
        inputFile = new FileInputStream(file);
        final boolean falg = copyFile(inputFile, outputStream);**
        if (falg)
            G.logToast("not sent");
        else
            G.logToast("sent");
    }
    catch (FileNotFoundException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
        G.logToast("not sent");
    }
    catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } finally {

        try {
            outputStream.flush();
        }
        catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

public static boolean copyFile(InputStream inputStream, OutputStream out) {
    byte[] buffer = new byte[4096];

    try {
        while (inputStream.read(buffer) > 0) {
            out.write(buffer);
        }
    }
    catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } finally
    {
        try {
            inputStream.close();
        }
        catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    return true;
}

and this is my read code :

private void readInputStream() {
    // TODO Auto-generated method stub
    while (true) {
        FileOutputStream fos = null;
        try {

            int mode = dataInputStream.readInt();
            G.logW("mode : " + mode);
            if (mode != G.FILE_MODE && mode != G.COMMAND_MODE)
                continue;
            int len = (int) dataInputStream.readLong();
            G.logW("len : " + len);
            file.delete();
            fos = new FileOutputStream(file);
            if (mode == G.COMMAND_MODE)
            {
                byte[] buffer = new byte[len];
                dataInputStream.read(buffer, 0, len);
                analizeCommand(new String(buffer));
            } else if (mode == G.FILE_MODE) {
                byte[] buffer = new byte[4096];

                int filesize = len; // Send file size in separate msg
                int read = 0;
                int totalRead = 0;
                int remaining = filesize;
                while ((read = dataInputStream.read(buffer, 0, Math.min(buffer.length, remaining))) > 0) {
                    totalRead += read;
                    remaining -= read;
                    System.out.println("read " + totalRead + " bytes.");
                    fos.write(buffer, 0, read);
                }
                playRecord();

                G.logW("new file received ");
            }
        }
        catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally
        {
            if (fos != null) {
                try {
                    fos.flush();
                }
                catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                try {
                    fos.close();
                }
                catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

        }

    }
}

But when I want to analyze the message on another device, I find that it shows the wrong values

this is my log in Destination device :

01-25 10:32:36.730 E/SMD     (  129): DCD ON
01-25 10:32:36.970 E/Watchdog(  490): !@Sync 653
01-25 10:32:39.720 W/tag     ( 1917): mode : 2
01-25 10:32:39.730 E/SMD     (  129): DCD ON
01-25 10:32:39.730 W/tag     ( 1917): len : 35840
01-25 10:32:39.750 W/PowerManagerService(  490): Timer 0x3->0x3|0x0
01-25 10:32:41.500 W/tag     ( 1917): new file received 
01-25 10:32:41.500 W/tag     ( 1917): mode : 8323227
01-25 10:32:41.500 W/tag     ( 1917): mode : 13828289
01-25 10:32:41.500 W/tag     ( 1917): mode : 14483649
01-25 10:32:41.510 W/tag     ( 1917): mode : 10813557
01-25 10:32:41.510 W/tag     ( 1917): mode : 4653117
01-25 10:32:41.510 W/tag     ( 1917): mode : 3473461
01-25 10:32:41.510 W/tag     ( 1917): mode : 3473433
01-25 10:32:41.520 W/tag     ( 1917): mode : 1638425
01-25 10:32:41.520 W/tag     ( 1917): mode : 1638425
01-25 10:32:41.520 W/tag     ( 1917): mode : 1638425
01-25 10:32:41.520 W/tag     ( 1917): mode : 65516
01-25 10:32:41.520 W/tag     ( 1917): mode : -3735638
01-25 10:32:41.530 W/tag     ( 1917): mode : -9240708
01-25 10:32:41.530 W/tag     ( 1917): mode : -7405692
01-25 10:32:41.530 W/tag     ( 1917): mode : -2424890
01-25 10:32:41.530 W/tag     ( 1917): mode : -1900554
01-25 10:32:41.530 W/tag     ( 1917): mode : -3080258
01-25 10:32:41.530 W/tag     ( 1917): mode : -4259954
01-25 10:32:41.530 W/tag     ( 1917): mode : -8061070
01-25 10:32:41.540 W/tag     ( 1917): mode : -8585330
01-25 10:32:41.540 W/tag     ( 1917): mode : -8061052
01-25 10:32:41.540 W/tag     ( 1917): mode : -8061080
01-25 10:32:41.540 W/tag     ( 1917): mode : -10420384
01-25 10:32:41.540 W/tag     ( 1917): mode : -10420384

Why is this happening?


Solution

  • socket read wrong data from dataInputStream

    No. You sent it wrong.

    1. Classic copy loop error.

      while (inputStream.read(buffer) > 0) {
          out.write(buffer);
      

      That should be

      int count;
      while ((count = inputStream.read(buffer)) > 0) {
          out.write(buffer, 0, count);
      

      At present you are writing garbage at end of stream, and more data than you advertised to the peer, so the peer is getting out of sync with the application protocol.

    2. Command reading problem:

      dataInputStream.read(buffer, 0, len);
      

      This is where you read the command. It should be:

      dataInputStream.readFully(buffer, 0, len);
      
    3. file.delete(); before fos = new FileOutputStream(file); is redundant.

    4. You're sending the length as a long and then downcasting it to int, and using int for the remaining count as well. Why? That means you can't send more than 2GB, and it also means that if you do your code will go back into this same bozo mode. The answer of mine from which you appear to have copied this code uses long. Why change it?