通过套接字发送大文件

时间:2012-07-12 12:58:21

标签: java

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

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

1 个答案:

答案 0 :(得分:3)

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

long size = clientData.readLong();

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

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