通过 java socket 编程共享的文件最终在接收端损坏 [英] Files shared through java socket programming end up being corrupt at the receiving end

查看:70
本文介绍了通过 java socket 编程共享的文件最终在接收端损坏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个客户端/服务器程序,允许服务器和客户端相互发送文件.我创建了套接字,并将客户端连接到服务器.我现在在同一台电脑上做这个.如果它完善了,我会把它带到另一台电脑上试试.

I am trying to create a client/server program that allows a server and client to send files to each other. I created the sockets, and connected the client to the server. I am doing this one the same computer for now. if it is perfected, i will take it to another computer and try it.

我的问题是文件传输成功但已损坏.收到的文件已损坏,但原始文件没问题.我遇到了套接字异常问题,其中套接字在发送文件后不断重置,但我已经设法解决了这个问题.现在文件已发送,但尚未完成.

My problem is that the file is transferred successfully but it is corrupt. the file received is corrupt, but the original is okay. I've had problems with socket exception where the socket keeps resetting after sending the file, but I've managed to solve that problem. Now the file is sent, but it is not complete.

接收到的文件大小小于发送的文件大小,导致接收到的文件无法工作.我通过网络发送了一个pdf文件.原来是695kb左右,但是收到的文件是688kb,导致文件损坏.我也尝试发送视频,并得到了相同的结果.接收的文件小于发送的文件.

The size of the file received is smaller than the size of the file sent, and this causes the received file not work. I sent a pdf file over the network. the original was about 695kb, but the received file was 688kb, and this caused the document to be corrupt. I also tried sending a video, and had the same result. the received file is smaller than the sent file.

我已经检查了程序,但我看不出问题出在哪里.我尝试实现的发送方法是零复制方法,其中文件中的数据直接发送到套接字,从那里直接读取到文件.我没有使用将它发送到输出流之前将其存储在缓冲区中的其他方法.这是因为我希望能够使用该程序发送大文件.大文件会填满java堆内存,而且这种方法速度更快.

I have checked the program, but I can't see where the problem is coming from. The sending method i try to implement is the zero-copy method, where the data from the file is sent directly to the socket, from where it is read directly to the file. i did not use the other method where it is stored in a buffer before it is sent to the output stream. This is because I want to be able to use the program to send large files. Large files will fill up the java heap memory, and besides this method is faster.

缓冲方法:

....
File file = new File("path to file);
BufferedInputStream = new BufferedInputStream(new FileInputStream(file));
BufferedOutputStream out = new      BufferedOutputStream(socket.getOutputStream());

byte[] buf = new byte[length];
in.read(buf, 0, buf.length);
out.write(buf, 0, buf.length);
....

我没有使用这种缓冲方法.这是我的代码.这是文件服务器

I did not use this buffer method. Here is my code. This is the file server

import java.io.*;
import java.net.*;

import javax.swing.JFileChooser;

public class ShareServer {

    public static void main(String args[]) {
        int port = 4991;
        ServerSocket server;
        Socket socket = null;
        BufferedInputStream in = null;
        BufferedOutputStream out = null;

        try {
            server = new ServerSocket(port);
            System.out.println("Waiting for connection request..");

            socket = server.accept();

            System.out.println("Connected to " + socket.getInetAddress().getHostName());

            JFileChooser fc = new JFileChooser();
            File file = null;

            if (fc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION)
                file = fc.getSelectedFile();

            // send out the reference of the file using writeObject() method
            new ObjectOutputStream(socket.getOutputStream()).writeObject(file);

            in = new BufferedInputStream(new FileInputStream(file));
            out = new BufferedOutputStream(socket.getOutputStream());

            // send file
            int b = 1;
            while (b != -1){
                b = in.read();
                out.write(b);
            }

            System.out.println(file.getName() + " has been sent successfully!");

        } catch (Exception e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }

        try {
            in.close();
            out.close();
            socket.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

这是客户端类:

import java.io.*;
import java.net.*;

import javax.swing.JOptionPane;

public class ShareClient {
    public ShareClient() {

    }

    public static void main(String[] args) throws IOException, ClassNotFoundException {

        String host = InetAddress.getLocalHost().getHostAddress();

        Socket socket = new Socket(host, 4991);
        System.out.println("Connected to " + host);

        // receive the file object. this does not contain the file data
        File refFile = (File) new ObjectInputStream(socket.getInputStream()).readObject();

        System.out.println("File to receive " + refFile.getName());

        // create a new file based on the refFile
        File newFile = new File(System.getProperty("user.home") + "/desktop/ReceivedFiles", refFile.getName());

        BufferedInputStream in = new BufferedInputStream(socket.getInputStream());
        BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(newFile));

        System.out.println("Receiving file now...");

        int b;
        while ((b = in.read()) != -1)
            out.write(b);

        System.out.println("File has been received successfully!");

        socket.close();

    }

}

服务器和客户端类成功运行,没有任何异常,文件被发送,但它已损坏.这是不完整的.请注意,通过ObjectInput 和ObjectOutput 流发送的文件并不是真正的文件,而只是一个包含我要发送的文件的所有信息的文件对象,但没有文件的二进制数据.

The server and the client classes run successfully without any exceptions, and the file is sent, but it is corrupt. it is incomplete. Take note that the file sent through the ObjectInput and ObjectOutput streams is not the real file, but just a file object that has all the information of the filie i want to send, but not the binary data of the file.

请问有人可以帮我吗?为什么文件损坏或不完整?它被读取到最后(当 -1 时)返回,并发送所有字节,但由于某种原因我无法解释,它最终小于原始文件的大小.

Please can anybody help me? Why is the file corrupt or incomplete? It is read to the end (when -1) is returned, and all the bytes are sent, but for some reason i can't explain, it ends up being less than the size of the original file.

推荐答案

目前,您将 -1 写在文件的末尾(此时您应该停止).类似的东西,

Currently, you write -1 at the end of the file (that's when you should stop). Something like,

int b = 1;
while (b != -1){
    b = in.read();
    if (b != -1) {
        out.write(b);
    }
}

int b;
while ((b = in.read()) != -1) {
    out.write(b);
}

这篇关于通过 java socket 编程共享的文件最终在接收端损坏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆