有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

通过socket发送时java文件已损坏

我只是试着从一个socket发送一些文件,我能够不受任何干扰地发送这些文件:同样,不管文件大小是大是小,它都像一个符咒一样发送

但在我的案例中出现的问题是,我发送的文件被破坏了,也就是说,它不像音频或视频那样播放。我已经经历了this,但没有帮助

下面是我正在使用的代码

服务器端:

File file = new File(
                Environment.getExternalStorageDirectory(),
                "testingFile.mp4");
        byte[] mybytearray = new byte[4096];
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(file);
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        }
        BufferedInputStream bis = new BufferedInputStream(fis);
        DataInputStream dis = new DataInputStream(bis);
        OutputStream os;
        DataOutputStream dos = null;
        try {
            os = socket.getOutputStream();
            dos = new DataOutputStream(os);
            dos.writeUTF(file.getName());
            dos.writeLong(mybytearray.length);
            int read;
            while ((read = dis.read(mybytearray)) != -1) {
                dos.write(mybytearray, 0, read);
            }
            socket.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            try {
                if (dos != null) {
                    dos.flush();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

以及客户端:

File file = new File(
                    Environment.getExternalStorageDirectory(),
                    "TEST SUCCESS.mp4");
            InputStream in = null;
            int bufferSize;

            try {
                bufferSize = socket.getReceiveBufferSize();
                in = socket.getInputStream();
                DataInputStream clientData = new DataInputStream(in);
                String fileName = clientData.readUTF();
                System.out.println(fileName);
                OutputStream output = new FileOutputStream(
                        file);
                byte[] buffer = new byte[bufferSize];
                int read;
                while ((read = clientData.read(buffer)) != -1) {
                    output.write(buffer, 0, read);
                }
                output.flush();
                socket.close();

            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                if (in != null) {
                    in.close();
                }

            }

提前谢谢


共 (2) 个答案

  1. # 1 楼答案

    因此,在评论和@Marqueisoflorne中的对话之后,请删除我在服务器端代码中写的行。i、 e从服务器端代码中删除这一行:

    dos.writeLong(mybytearray.length);
    

    或者在客户端代码中编写以下代码:

    long sizeOfFile = clientData.readLong();
    

    它解决了这个问题

  2. # 2 楼答案

    服务器端

    您的代码发送缓冲区长度(4096),这是一个错误

    它应该发送文件长度

    File file = new File( ... );
    try {
        //dos.writeLong(mybytearray.length);
        dos.writeLong(file.length());
    
    }
    

    客户端

    服务器发送两个元数据

    • 文件名(F字节,由utf-8编码)
    • 文件长度(8字节)

    然后发送整个内容(N字节)

    但客户端代码忽略文件长度(8字节),只读取文件名和内容N字节

        in = socket.getInputStream();
        DataInputStream clientData = new DataInputStream(in);
    
        String fileName = clientData.readUTF(); // ok read F bytes
        
        // missing readLong(..) 8 bytes
        // long fileLen = clientData.readLong(); <= read file length before reading contents
        
        // read N bytes, but first 8 bytes are file length, which are written into file.
        int read;
        while ((read = clientData.read(buffer)) != -1) {
            output.write(buffer, 0, read);
        }
    

    不要依赖-1

    你的代码一直依赖于while循环中的-1

      while ((read = dis.read(mybytearray)) != -1) {
        dos.write(mybytearray, 0, read);
      }
    
      while ((read = clientData.read(buffer)) != -1) {
        output.write(buffer, 0, read);
      }
    
    

    -1表示异常状态

    因为服务器知道文件的确切大小并写出文件,所以客户端应该从流中读取字节的确切长度

    若服务器发送1234字节,当客户端从clientData.read(..)读取-1时,它无法从流中读取内容,而不是流的结尾