javafilesocketsspeed-test

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 accurate (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.


Solution

  • 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;