2011-08-04 72 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

您的代码无效。你在错误的时刻结束计时器。直到您刷新或关闭了输出流,传输才完成。