3

ローカル ネットワークの速度を測定できる小さな Java プログラムを作成しています。ソケットを扱うのは初めてですが、動作するプログラムをまとめました。唯一の問題は、測定値が正確とはほど遠い (低すぎる) ことです。

これはサーバーコードです:

ServerSocket servsock = new ServerSocket(13267);
while (true) {
    System.out.println("Waiting...");

    Socket sock = servsock.accept();
    System.out.println("Accepted connection : " + sock);

    File myFile = new File("test.txt");
    FileInputStream in = new FileInputStream(myFile);
    OutputStream out = sock.getOutputStream();

    int bytes = 0;
    byte[] buffer = new byte[8192];
    int len;

    while ((len = in.read(buffer)) > 0) {
        out.write(buffer, 0, len);
        bytes += len;
    }

    System.out.println("Transfer completed, " + bytes + " bytes sent");

    out.flush();
    sock.close();
}

これはクライアント コードです。

Socket sock = new Socket("192.168.0.100", 13267);
System.out.println("Connecting to : " + sock);

InputStream in = sock.getInputStream();
FileOutputStream out = new FileOutputStream("received.txt");

int bytes = 0;
byte[] buffer = new byte[8192];
int len;

long start = System.currentTimeMillis();

while ((len = in.read(buffer)) > 0) {
    out.write(buffer, 0, len);
    bytes += len;
}

long end = System.currentTimeMillis();

out.close();
sock.close();

double kbps = (bytes / 1000) / ((end - start) / 1000);
System.out.println("Speed: " + kbps + " kbps");

これは、すべてを遅くする独自のバッファを使用しているためですか、それとも何が問題なのですか? ヒントやヒントも大歓迎です。

4

3 に答える 3

4

ファイルを送信する必要がない帯域幅を測定する場合は、空のデータを送信するだけでかまいません。ファイルが十分に大きくない場合、接続を確立するためのコスト (通常は 20 ミリ秒) により、接続が遅く見えるようになります。

少なくとも 2 ~ 10 秒間データを送信することをお勧めします。

この記事には、ソケットを介してデータを転送する最速の方法に関するサンプル コードがあります。Java ソケットの速度


整数演算を使用して浮動小数点を生成すると、エラーが発生する可能性があります。

double kbps = (bytes / 1000) / ((end - start) / 1000);

2100bytesend - start1900 とします。

double kbps = (2100 / 1000) / (1900 / 1000);
double kbps = 2 / 1; == 2.

とほとんど同じです (ただし、誤差は少なくなります)。

double kbps = bytes / (end - start);

より良い

double kbps = (double) bytes / (end - start);

空データを送信するには

byte[] bytes = new byte[8*1024];
OutputStream out = socket.getOutputStream();
// send data for given amount of time, e.g. 2000 ms
long endTime = System.currentTimeMS() + timeToSendDataMS;
do {
    out.write(bytes);
} while(endTime > System.currentTimeMS());

空のデータを読み取るには

long total = 0;
byte[] bytes = new byte[8*1024];
InputStream in = socket.getInputStream();
int len;
while((len = in.read(bytes)) != -1)
    total += len;
于 2011-08-04T17:54:27.127 に答える
0

あなたのコードは無効です。間違った時点でタイマーを終了しています。出力ストリームをフラッシュまたはクローズするまで、転送は完了しません。

于 2011-08-05T01:39:48.247 に答える