6

ネットワーク経由でファイルを送信する必要があるアプリケーションを作成しています。私はこれまで (大学 1 年生のとき) 標準の java.net および java.io クラスの使用方法しか教えられていないため、java.nio や netty などの優れた機能については経験がありません。次のように、Socket および ServerSocket クラスと BufferedInput/OutputStreams および BufferedFile ストリームを使用して、サーバー/クライアントをセットアップしました。

サーバー:

    public class FiletestServer {

    static ServerSocket server;
    static BufferedInputStream in;
    static BufferedOutputStream out;

    public static void main(String[] args) throws Exception {
    server = new ServerSocket(12354);
    System.out.println("Waiting for client...");
    Socket s = server.accept();
    in = new BufferedInputStream(s.getInputStream(), 8192);
    out = new BufferedOutputStream(s.getOutputStream(), 8192);
    File f = new File("test.avi");
    BufferedInputStream fin = new BufferedInputStream(new FileInputStream(f), 8192);

    System.out.println("Sending to client...");
    byte[] b = new byte[8192];
    while (fin.read(b) != -1) {
        out.write(b);
    }
    fin.close();
    out.close();
    in.close();
    s.close();
    server.close();
    System.out.println("done!");
    }
}

そしてクライアント:

public class FiletestClient {

    public static void main(String[] args) throws Exception {
    System.out.println("Connecting to server...");
    Socket s;
    if (args.length < 1) {
        s = new Socket("", 12354);
    } else {
        s = new Socket(args[0], 12354);
    }
    System.out.println("Connected.");
    BufferedInputStream in = new BufferedInputStream(s.getInputStream(), 8192);
    BufferedOutputStream out = new BufferedOutputStream(s.getOutputStream(), 8192);
    File f = new File("test.avi");
    System.out.println("Receiving...");
    FileOutputStream fout = new FileOutputStream(f);
    byte[] b = new byte[8192];
    while (in.read(b) != -1) {
        fout.write(b);
    }
    fout.close();
    in.close();
    out.close();
    s.close();
    System.out.println("Done!");
    }
}

最初はバッファリングを使用せず、in.read() から各 int を書き込んでいました。Windows 7 のネットワーク モニター ガジェットによると、約 200kb/s の転送が得られました。その後、上記のように変更しましたが、4096 バイトのバッファーを使用して同じ速度を得ましたが、受信したファイルは通常、ソース ファイルよりも数キロバイト大きく、それが私の問題です。バッファ サイズを 8192 に変更したところ、ワイヤレス経由でラップトップに約 3.7 ~ 4.5 mb/秒の転送速度が得られました。これは今のところ十分に高速ですが、ファイルがわずかに大きくなるという問題がまだ残っています (これにより、受信時に md5/sha ハッシュ テストに失敗する)。

だから私の質問は、まともな速度を得て、反対側でまったく同じファイルになるための適切なバッファリング方法は何ですか? もう少し速くなればいいのですが、今のところ速度に満足しています。ある時点までは、より大きなバッファーの方が優れていると想定しています。その点が何であるかを見つける必要があるだけです。

4

2 に答える 2

5

実際に読み取られるデータのサイズを無視しています。

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

1 バイトしか読み取れない場合でも、常に 8192 バイトを書き込みます。代わりに、使用することをお勧めします

for(int len; ((len = in.read(b)) > 0;)
   fout.write(b, 0, len);

バッファは byte[] と同じサイズなので、現時点では実際には何もしていません。

ほとんどのネットワークの MTU は約 1500 バイトであり、低速ネットワーク (最大 1 GB) で最大 2 KB のパフォーマンスが向上します。8KBでも結構です。それよりも大きいと、役に立たない可能性があります。

于 2012-09-03T12:10:58.173 に答える
0

実際に「完璧」にしたい場合は、try-catch-with-resources ステートメントjava.nio パッケージ(または nio 派生ライブラリ) を確認する必要があります。

于 2012-09-03T12:08:58.410 に答える