开发者

Java network file transfer problem

I am writing a small java program that can measure the speed of my local network. It is the first time I am working with sockets but I've put together a program that works. The only problem is that the measurements are far from accurat开发者_JAVA百科e (way too low).

This is the server code:

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();
}

This is the client code:

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");

Is this because I am working with my own buffers that slow everything down or what could be the problem? Tips & hints are welcome too.


If you want to measure bandwidth you don't need to send a file, you can just send blank data. If the file isn't large enough, the cost of making the connection (typically 20 ms) will make your connection appear slow.

I suggest you send data for at least 2 to 10 seconds.

This article has sample code on the fastest way to transfer data over a socket. How fast are Java sockets


Using integer arithmetic to produce a floating point is likely to get errors.

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

Say bytes is 2100 and end - start is 1900 you will get

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

is almost the same as (but with less error)

double kbps = bytes / (end - start);

better

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

To send blank data

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());

To read blank data

long total = 0;
byte[] bytes = new byte[8*1024];
InputStream in = socket.getInputStream();
int len;
while((len = in.read(bytes)) != -1)
    total += len;


It's because you write to disk each 8K package that you receive on the client side.

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

This is not necessary for a speed test. Just reading the bytes into the buffer, is enough. Skip writing the packages to file in the client code. Optionally, you could write the received packages into a ByteArrayOutputStream. Java will handle the allocation itself in the JVM's heap space. And it will not biase the speed test.


Your code is invalid. You're ending the timer at the wrong point. The transfer isn't complete until you have flushed or closed the output stream.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜