使用套接字通过本地网络传输文件时,如何防止文件损坏?

时间:2019-10-14 12:13:09

标签: java file sockets tcp file-handling

我正在做一个学校项目,我想制作一个个人存储服务器。目前,我试图实现的目标是能够将文件从客户端计算机传输到服务器。但是,在使用映像进行测试时,文件在损坏之前会部分发送。 请记住,我是一个相当新的程序员,并且我的技术知识可能会有所限制。

我正在通过DataOutputStream使用字节数组来传输文件。我想使用此方法,因为它适用于任何文件类型。我试图将缓冲区大小设置为文件的确切大小,并且更大,但是都没有用。

服务器:

public void run() {
            try {
                System.out.println("ip: " + clientSocket.getInetAddress().getHostAddress());

                out = new DataOutputStream(clientSocket.getOutputStream());
                in = new DataInputStream(clientSocket.getInputStream());

                in.read(buffer, 0, buffer.length);

                fileOut = new FileOutputStream("X:\\My Documents\\My 
                Pictures\\gradient.jpg");

                fileOut.write(buffer, 0, buffer.length);
                in.close();
                out.close();
                clientSocket.close();

         } catch (IOException ex) {
                System.out.println(ex.getMessage());
            }
        }

客户:

 public void startConnection(String ip, int port) {
        try {
            clientSocket = new Socket(ip, port);
            out = new DataOutputStream(clientSocket.getOutputStream());
            in = new DataInputStream(clientSocket.getInputStream());

            x = false;
            Path filePath = Paths.get("C:\\Users\\georg\\Documents\\gradient.jpg");
            buffer = Files.readAllBytes(filePath);
            Thread.sleep(3000);
            //Files.write(filePath, buffer);
            //out.write(buffer,0,buffer.length);
            x = true;
            sendMessage(buffer);


        } catch (IOException ex) {
            System.out.println(ex.getMessage());
        } catch (InterruptedException ex) {
            Logger.getLogger(PCS_Client.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public byte[] sendMessage(byte[] buffer) {
        if (x==true){
        try {
            out.write(buffer,0,buffer.length);

        } catch (IOException ex) {
            System.out.println(ex.getMessage());
        }

    }
        return null;
    }

这是我尝试发送的文件与收到的文件的比较: https://imgur.com/gallery/T7nUUJT

奇怪的是,发送单色图像会在服务器上生成单色图像。我认为这里的问题可能必须在代码执行的时机,但是我不确定,也不知道如何解决它。

2 个答案:

答案 0 :(得分:1)

问题出在您的服务器代码中,此行:

in.read(buffer, 0, buffer.length);

您希望一次读取所有数据,但是如果您阅读该文档,则会发现以下内容:

  

public final int read(byte [] b,          诠释          int len)                  引发IOException

     

从包含的输入流中读取最多len字节的数据到一个   字节数组。尝试读取多达len个字节,但是   较小的数字可能被读取,可能为零。字节数   实际读取的结果以整数形式返回。

重要的部分是读取最多个字节。

您必须使用read的返回值,并将其重复调用为read,直到不再需要读取为止。

答案 1 :(得分:-1)

问题在于您如何从流中读取数据。可能无法一次读取所有字节,因此您将需要继续读取直到读取完所有字节(由返回的-1表示)。

为此可能的解决方案是

byte[] buffer = new byte[32768];
int bytesRead = 0;

while (bytesRead != -1) {
    try {
        bytesRead = in.read(buffer, 0, length);
        if (bytesRead != -1) {
            offset += bytesRead;
            fileOut.write(buffer, 0, bytesRead);
        }
    } catch (IOException ex) {

    }
}