通过套接字发送大文件 [英] Sending large files over socket

查看:123
本文介绍了通过套接字发送大文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究套接字文件发送方,它工作得很好,但我无法用它发送大文件。总是遇到堆错误。然后我改变了客户端的代码,所以它会以块的形式发送文件。现在我可以发送大文件,但是有新问题。现在我收到空的小文件和较大的文件,例如视频无法播放。以下是发送文件的客户端代码:

I got working over socket file sender, it worked perfectly, but I couldn't send large files with it. Always got heap error. Then I changed the code of client, so it would send file in chunks. Now I can send big files, but there is new problem. Now I recieve small files empty and larger files for example videos can't be played. Here is the code of client that sends file:

public void send(File file) throws UnknownHostException, IOException {

    // Create socket
    hostIP = "localhost";
    socket = new Socket(hostIP, 22333);

    //Send file

    FileInputStream fis = new FileInputStream(file);
    BufferedInputStream bis = new BufferedInputStream(fis);

    DataInputStream dis = new DataInputStream(bis);


    OutputStream os = socket.getOutputStream();

    //Sending size of file.
    DataOutputStream dos = new DataOutputStream(os);
    dos.writeUTF(file.getName() + ":" + userName);

    byte[] arr = new byte[1024];
    try {
        int len = 0;
        while ((len = dis.read(arr)) != -1) {
            dos.write(arr, 0, len);

        }
    } catch (IOException ex) {
        ex.printStackTrace();
    }



    dos.flush();

    socket.close();
}

这是服务器代码:

void start() throws IOException {

        // Starts server on port.
        serverSocket = new ServerSocket(port);

        int bytesRead;

        while (true) {
            connection = serverSocket.accept();

            in = connection.getInputStream();

            clientData = new DataInputStream(in);

            String[] data = clientData.readUTF().split(":");
            String fileName = data[0];
            String userName = data[1];

            output = new FileOutputStream("C:/" + fileName);
            long size = clientData.readLong();
            byte[] buffer = new byte[1024];

            // Build new file
            while (size > 0 && (bytesRead = clientData.read(buffer, 0, (int) Math.min(buffer.length, size))) != -1) {
                output.write(buffer, 0, bytesRead);
                size -= bytesRead;
            }
            output.close();
        }
    }


推荐答案

你无法将文件的长度写入客户端中的流:

You failed to write out the length of the file to the stream in the client:

long size = clientData.readLong();

因此,服务器中的调用正在读取实际文件的前8个字节,谁知道这是什么数量是。您不必从流中读取长度,因为您只写了一个文件。读完文件名和用户名后(不是很安全吗?)你可以直到EOF读取流。如果您想通过同一个打开的套接字发送多个文件,那么在读取文件之前您需要知道长度。

So that call in the server is reading the first 8 bytes of the actual file and who knows what that quantity is. You don't have to read the length from the stream since you only wrote a single file. After reading the filename, and username (not very secure is it?) you can just read the stream until EOF. If you ever wanted to send multiple files over the same open socket then you'd need to know the length before reading the file.

此外,您的阅读缓冲区是通过小。您应该至少为8192而不是1024.并且您希望将所有.close()放在finally块中,以确保您的服务器和客户端在出现异常时正确关闭。

Also your buffers for reading are way to small. You should be at a minimum of 8192 instead of 1024. And you'll want to put all .close() in a finally block to make sure your server and clients shutdown appropriately if there is an exception ever.

这篇关于通过套接字发送大文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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