2011-08-04 104 views
3

我在寫一個可以測量本地網絡速度的小型java程序。這是我第一次使用套接字工作,但我已經制定了一個可行的程序。唯一的問題是測量結果不準確(太低)。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

如果你想測量帶寬,你不需要發送文件,你可以發送空白數據。如果文件不夠大,建立連接的代價(通常爲20毫秒)會使連接顯得很慢。

我建議你發送數據至少2到10秒。

本文的示例代碼是通過套接字傳輸數據的最快方式。 How fast are Java sockets


使用整數算術來產生浮點很可能會得到錯誤。

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

bytes是2100和end - start是1900,你會得到

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; 
+0

謝謝你的答案,你如何發送空白數據? – Jens

+0

@Jens,我已將它添加到我的答案中。;) –

0

這是因爲你寫入到磁盤每個8K包,您在客戶端收到

FileOutputStream out = new FileOutputStream("received.txt"); 
... 
while ((len = in.read(buffer)) > 0) { 
    out.write(buffer, 0, len); 
    ... 
} 

這不是速度測試所必需的。只需將字節讀入緩衝區就足夠了。跳過將包寫入客戶端代碼中。 (可選)您可以將收到的包寫入ByteArrayOutputStream。 Java將在JVM的堆空間中處理分配本身。它不會偏見速度測試。

+0

謝謝,我已經刪除了輸出流。 – Jens

0

您的代碼無效。你在錯誤的時刻結束計時器。直到您刷新或關閉了輸出流,傳輸才完成。