Tuesday, July 22, 2025

Java Speed Test

# Java Network Speed Test Implementation

Here's a complete Java implementation to check network speed with download and upload testing:

## Network Speed Test Utility

```java
import java.io.*;
import java.net.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;

public class NetworkSpeedTest {
    private static final int BUFFER_SIZE = 8192;
    private static final int TEST_DURATION_SECONDS = 5;
    private static final String DOWNLOAD_TEST_URL = "http://ipv4.download.thinkbroadband.com/100MB.zip";
    private static final String UPLOAD_TEST_URL = "http://speedtest.tele2.net/upload.php";
    
    private final ExecutorService executor = Executors.newFixedThreadPool(2);
    private final AtomicLong totalDownloadBytes = new AtomicLong();
    private final AtomicLong totalUploadBytes = new AtomicLong();
    
    public static void main(String[] args) {
        NetworkSpeedTest tester = new NetworkSpeedTest();
        
        try {
            System.out.println("Starting network speed test...");
            
            // Run download test
            double downloadSpeed = tester.testDownloadSpeed();
            System.out.printf("Download Speed: %.2f Mbps%n", downloadSpeed);
            
            // Run upload test
            double uploadSpeed = tester.testUploadSpeed();
            System.out.printf("Upload Speed: %.2f Mbps%n", uploadSpeed);
            
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            tester.shutdown();
        }
    }
    
    public double testDownloadSpeed() throws Exception {
        totalDownloadBytes.set(0);
        long startTime = System.currentTimeMillis();
        
        Future<?> downloadFuture = executor.submit(() -> {
            try {
                URL url = new URL(DOWNLOAD_TEST_URL);
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                
                try (InputStream in = new BufferedInputStream(connection.getInputStream())) {
                    byte[] buffer = new byte[BUFFER_SIZE];
                    int bytesRead;
                    
                    while ((bytesRead = in.read(buffer)) != -1) {
                        totalDownloadBytes.addAndGet(bytesRead);
                        
                        // Check if test duration has elapsed
                        if ((System.currentTimeMillis() - startTime) >= TEST_DURATION_SECONDS * 1000) {
                            break;
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        
        // Wait for test duration
        Thread.sleep(TEST_DURATION_SECONDS * 1000);
        downloadFuture.cancel(true);
        
        long elapsedTime = System.currentTimeMillis() - startTime;
        return calculateMbps(totalDownloadBytes.get(), elapsedTime);
    }
    
    public double testUploadSpeed() throws Exception {
        totalUploadBytes.set(0);
        long startTime = System.currentTimeMillis();
        
        Future<?> uploadFuture = executor.submit(() -> {
            try {
                URL url = new URL(UPLOAD_TEST_URL);
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setDoOutput(true);
                connection.setRequestMethod("POST");
                
                try (OutputStream out = connection.getOutputStream()) {
                    byte[] buffer = new byte[BUFFER_SIZE];
                    // Fill buffer with random data
                    new java.util.Random().nextBytes(buffer);
                    
                    while (true) {
                        out.write(buffer);
                        totalUploadBytes.addAndGet(buffer.length);
                        
                        // Check if test duration has elapsed
                        if ((System.currentTimeMillis() - startTime) >= TEST_DURATION_SECONDS * 1000) {
                            break;
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        
        // Wait for test duration
        Thread.sleep(TEST_DURATION_SECONDS * 1000);
        uploadFuture.cancel(true);
        
        long elapsedTime = System.currentTimeMillis() - startTime;
        return calculateMbps(totalUploadBytes.get(), elapsedTime);
    }
    
    private double calculateMbps(long bytes, long millis) {
        if (millis == 0) return 0;
        double seconds = millis / 1000.0;
        double bits = bytes * 8;
        return (bits / seconds) / 1_000_000; // Convert to Mbps
    }
    
    public void shutdown() {
        executor.shutdownNow();
        try {
            if (!executor.awaitTermination(1, TimeUnit.SECONDS)) {
                executor.shutdownNow();
            }
        } catch (InterruptedException e) {
            executor.shutdownNow();
            Thread.currentThread().interrupt();
        }
    }
}
```

## Alternative Implementation with Progress Reporting

```java
import java.io.*;
import java.net.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;

public class AdvancedSpeedTest {
    private static final int TEST_DURATION = 10; // seconds
    private static final int PROGRESS_INTERVAL = 1; // seconds
    
    public static void main(String[] args) {
        System.out.println("Network Speed Test");
        System.out.println("------------------");
        
        SpeedTestResult downloadResult = testDownloadSpeed();
        System.out.printf("\nDownload: %.2f Mbps (%.2f MB/s)%n", 
            downloadResult.getMbps(), downloadResult.getMBps());
        
        SpeedTestResult uploadResult = testUploadSpeed();
        System.out.printf("Upload: %.2f Mbps (%.2f MB/s)%n", 
            uploadResult.getMbps(), uploadResult.getMBps());
    }
    
    public static SpeedTestResult testDownloadSpeed() {
        System.out.println("\nTesting download speed...");
        final String testUrl = "http://speedtest.ftp.otenet.gr/files/test100Mb.db";
        
        final AtomicLong totalBytes = new AtomicLong();
        final AtomicBoolean running = new AtomicBoolean(true);
        
        ExecutorService executor = Executors.newSingleThreadExecutor();
        Future<?> future = executor.submit(() -> {
            try {
                URL url = new URL(testUrl);
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                
                try (InputStream in = new BufferedInputStream(conn.getInputStream())) {
                    byte[] buffer = new byte[8192];
                    int bytesRead;
                    
                    while (running.get() && (bytesRead = in.read(buffer)) != -1) {
                        totalBytes.addAndGet(bytesRead);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        
        return runSpeedTest(totalBytes, running, future, executor);
    }
    
    public static SpeedTestResult testUploadSpeed() {
        System.out.println("\nTesting upload speed...");
        final String testUrl = "http://speedtest.tele2.net/upload.php";
        
        final AtomicLong totalBytes = new AtomicLong();
        final AtomicBoolean running = new AtomicBoolean(true);
        
        ExecutorService executor = Executors.newSingleThreadExecutor();
        Future<?> future = executor.submit(() -> {
            try {
                URL url = new URL(testUrl);
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setDoOutput(true);
                conn.setRequestMethod("POST");
                
                try (OutputStream out = conn.getOutputStream()) {
                    byte[] buffer = new byte[8192];
                    // Fill with random data
                    new java.util.Random().nextBytes(buffer);
                    
                    while (running.get()) {
                        out.write(buffer);
                        totalBytes.addAndGet(buffer.length);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        
        return runSpeedTest(totalBytes, running, future, executor);
    }
    
    private static SpeedTestResult runSpeedTest(AtomicLong totalBytes, AtomicBoolean running, 
                                             Future<?> future, ExecutorService executor) {
        long startTime = System.currentTimeMillis();
        long lastPrintTime = startTime;
        long lastBytes = 0;
        
        try {
            for (int i = 0; i < TEST_DURATION; i++) {
                Thread.sleep(1000);
                
                long currentBytes = totalBytes.get();
                long currentTime = System.currentTimeMillis();
                long elapsedMillis = currentTime - startTime;
                
                // Calculate current speed
                double mbps = ((currentBytes - lastBytes) * 8.0) / (1_000_000); // Mbps per interval
                System.out.printf("\rCurrent speed: %.2f Mbps  ", mbps);
                
                lastBytes = currentBytes;
                lastPrintTime = currentTime;
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            running.set(false);
            future.cancel(true);
            executor.shutdownNow();
        }
        
        long endTime = System.currentTimeMillis();
        long totalMillis = endTime - startTime;
        return new SpeedTestResult(totalBytes.get(), totalMillis);
    }
    
    static class SpeedTestResult {
        private final long bytes;
        private final long millis;
        
        public SpeedTestResult(long bytes, long millis) {
            this.bytes = bytes;
            this.millis = millis;
        }
        
        public double getMbps() {
            if (millis == 0) return 0;
            return (bytes * 8.0 / (millis / 1000.0)) / 1_000_000;
        }
        
        public double getMBps() {
            if (millis == 0) return 0;
            return (bytes / (millis / 1000.0)) / 1_000_000;
        }
    }
}
```

## Key Features:

1. **Accurate Speed Measurement**:
   - Measures both download and upload speeds
   - Calculates in Mbps (Megabits per second) and MB/s (Megabytes per second)
   - Uses proper unit conversion (1 byte = 8 bits)

2. **Testing Methodology**:
   - Download test: Downloads a large file from a speed test server
   - Upload test: Uploads generated data to a speed test server
   - Configurable test duration

3. **Thread Management**:
   - Uses separate threads for network operations
   - Properly shuts down executors when finished
   - Can cancel ongoing tests if needed

4. **Progress Reporting**:
   - Shows real-time speed during the test
   - Prints final results in human-readable format

5. **Error Handling**:
   - Catches and reports network errors
   - Handles thread interruption properly

To use this code, simply run the main class. The test will automatically measure both download and upload speeds and display the results. You can adjust the `TEST_DURATION` constant to change how long each test runs.

No comments: