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 までストリームを読み取ることができます。同じ開いているソケットで複数のファイルを送信したい場合は、ファイルを読み取る前に長さを知る必要があります。

また、読み取り用のバッファが小さすぎます。最低でも 1024 ではなく 8192 にする必要があります。例外が発生した場合にサーバーとクライアントが適切にシャットダウンするように、すべての .close() を finally ブロックに配置する必要があります。

于 2012-07-12T13:09:21.700 に答える