1

我在套接字文件发送器上工作,它工作得很好,但我不能用它发送大文件。总是出现堆错误。然后我改变了客户端的代码,所以它会分块发送文件。现在我可以发送大文件,但出现了新问题。现在我收到了空的小文件和较大的文件,例如无法播放视频。这是发送文件的客户端代码:

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

1 回答 1

3

您未能将文件的长度写入客户端中的流:

long size = clientData.readLong();

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

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

于 2012-07-12T13:09:21.700 回答