【问题标题】:socket read wrong data from dataInputStream套接字从 dataInputStream 读取错误数据
【发布时间】:2017-08-16 20:43:49
【问题描述】:

我想通过本地 Wi-Fi 网络将文本和文件发送到我的应用程序中,我考虑以这种格式进行任何通信:

1字节消息模式(文件或文本)+长为消息长度+消息(文本或文件)

这是我写的代码:

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;
}

这是我的阅读代码:

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();
                }
            }

        }

    }
}

但是当我想在另一个设备上分析消息时,我发现它显示的值有误

这是我登录的目标设备:

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

为什么会这样?

【问题讨论】:

    标签: android sockets datainputstream


    【解决方案1】:

    socket 从 dataInputStream 读取错误数据

    没有。你发错了。

    1. 经典的复制循环错误。

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

      应该是这样的

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

      目前,您在流的末尾写入垃圾,并且比您向对等点通告的数据多,因此对等点与应用程序协议不同步。

    2. 命令读取问题:

      dataInputStream.read(buffer, 0, len);
      

      这是您阅读命令的地方。应该是:

      dataInputStream.readFully(buffer, 0, len);
      
    3. file.delete(); 之前的fos = new FileOutputStream(file); 是多余的。

    4. 您将长度作为long 发送,然后将其向下转换为int,并将int 用于剩余计数。为什么?这意味着您不能发送超过 2GB 的数据,这也意味着如果您这样做,您的代码将回到同样的 bozo 模式。您似乎从中复制了此代码的我的答案使用long。为什么要改变它?

    【讨论】:

    • منون مشکل حل شد تقریبا عزیزم
    【解决方案2】:
      while (inputStream.read(buffer) > 0) {
            out.write(buffer);
        }
    

    应该是:

     int len = 0;
    while ((len = inputStream.read(buffer)) >= 0) {
           // if len equals 0, you should read continue.
            if(len  > 0)
           {
               out.write(buffer,0,len);
           }
        }
    

    【讨论】:

    • 如果buffer.length 为零,Read 只能返回零,这是一个编程错误,你不想循环,所以循环条件应该是> 0,而不是@987654325 @。 len > 0 测试毫无意义。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-07
    • 1970-01-01
    • 2015-06-26
    • 2014-06-07
    • 2016-06-10
    • 2016-02-20
    相关资源
    最近更新 更多