# How SpeedtestService Measures Server Latency and Bandwidth in v2rayN

> Discover how SpeedtestService measures server latency and bandwidth in v2rayN using TCP handshakes, ICMP pings, and proxy tunnel tests. Learn the technical details.

- Repository: [2dust/v2rayN](https://github.com/2dust/v2rayN)
- Tags: deep-dive
- Published: 2026-02-27

---

**SpeedtestService measures server latency through raw TCP handshakes and ICMP-like pings routed through local SOCKS5 proxies, then calculates bandwidth by downloading test files via the same proxy tunnel, storing all metrics through ProfileExManager for UI display.**

The **SpeedtestService** class in the open-source v2rayN client (`2dust/v2rayN`) provides comprehensive network performance testing for V2Ray/Xray server configurations. Located in [`v2rayN/ServiceLib/Services/SpeedtestService.cs`](https://github.com/2dust/v2rayN/blob/main/v2rayN/ServiceLib/Services/SpeedtestService.cs), this service orchestrates concurrent latency and bandwidth measurements while managing proxy lifecycle and UI updates through injected callbacks.

## Architecture and Core Components

According to the `2dust/v2rayN` source code, the service operates through an injected update callback (`_updateFunc`) that streams `SpeedTestResult` objects to the UI in real-time. It supports cancellation via `ExitLoop()` and uses semaphores to manage concurrent test execution safely. All results persist through `ProfileExManager.Instance`, which stores delay and speed metrics for each server profile using `SetTestDelay` and `SetTestSpeed` methods.

## Measuring Server Latency (Ping)

The service implements two distinct latency measurement paths depending on whether you need rapid screening or accurate proxy-path latency.

### TCP Handshake Latency Measurement

For rapid latency assessment without establishing a full proxy tunnel, the `RunTcpingAsync` method calls `GetTcpingTime` at [`v2rayN/ServiceLib/Services/SpeedtestService.cs`](https://github.com/2dust/v2rayN/blob/main/v2rayN/ServiceLib/Services/SpeedtestService.cs) (lines 323-352). This function opens a raw TCP socket directly to the server's address and port, measuring the elapsed milliseconds between `ConnectAsync` initiation and successful connection completion. The implementation enforces a 5-second timeout, providing a quick "handshake" latency ideal for fast server screening.

### Real Ping via SOCKS5 Proxy

For accurate latency through the actual encrypted path, `RunRealPingAsync` launches a temporary local SOCKS5 listener using the server's configuration. It invokes `ConnectionHandler.GetRealPingTime` with the configurable test URL specified in `_config.SpeedTestItem.SpeedPingTestUrl`, sending ICMP-like probes through the established proxy tunnel. This measures true round-trip time from the client through the V2Ray/Xray server to the target destination, with results stored via `ProfileExManager.Instance.SetTestDelay`.

## Measuring Bandwidth (Speed Test)

Bandwidth measurement occurs only after successful latency verification when the `blSpeedTest` parameter is true.

### Download-Based Throughput Calculation

The `DoSpeedTest` method (located in [`SpeedtestService.cs`](https://github.com/2dust/v2rayN/blob/main/SpeedtestService.cs)) creates a `WebProxy` instance pointing to the local SOCKS5 listener for the target server configuration. It calls `DownloadService.DownloadDataAsync`, which utilizes `DownloaderHelper.Instance.DownloadDataAsync4Speed` to fetch the test file configured in `_config.SpeedTestItem.SpeedTestUrl`.

The download helper executes the HTTP GET request through the proxy tunnel and returns the measured speed as a formatted string (e.g., "12.34"). The service parses this to a decimal value and persists it via `ProfileExManager.Instance.SetTestSpeed`, providing realistic throughput data for the specific server configuration.

## Practical Implementation Example

The following example demonstrates initializing the service and executing a comprehensive speed test:

```csharp
// Load configuration and define UI callback
var config = Config.Load();
Func<SpeedTestResult, Task> updateFunc = async result =>
{
    Console.WriteLine($"Server {result.IndexId}: {result.Delay}ms delay, {result.Speed}MB/s");
};

// Initialize service with configuration and callback
var speedtest = new SpeedtestService(config, updateFunc);

// Execute full speed test (latency + bandwidth)
await speedtest.RunLoop(ESpeedActionType.Speedtest, selectedProfileItems);

```

To cancel an ongoing test programmatically:

```csharp
speedtest.ExitLoop(); // Signals cancellation via exit-loop key

```

## Summary

- **Dual latency modes**: TCP handshake for quick checks (`GetTcpingTime`) and full proxy ping for path-accurate measurements (`ConnectionHandler.GetRealPingTime`).
- **Bandwidth measurement**: Downloads test files through SOCKS5 proxies using `DownloadService.DownloadDataAsync` and `DownloaderHelper.Instance.DownloadDataAsync4Speed`.
- **Data persistence**: All metrics store through `ProfileExManager.Instance` using `SetTestDelay` and `SetTestSpeed` methods.
- **Concurrency control**: Semaphores manage parallel tests while `ExitLoop()` provides thread-safe cancellation support.
- **Configuration-driven**: Test URLs are configurable via `_config.SpeedTestItem.SpeedPingTestUrl` (latency) and `_config.SpeedTestItem.SpeedTestUrl` (bandwidth).

## Frequently Asked Questions

### What is the difference between TCP ping and Real ping in v2rayN SpeedtestService?

TCP ping (`GetTcpingTime`) measures raw TCP connection latency to the server endpoint without proxy overhead, suitable for quick server screening. Real ping routes ICMP-like probes through the established SOCKS5 proxy tunnel via `ConnectionHandler.GetRealPingTime`, measuring true round-trip time through the encrypted forwarding path.

### Where does SpeedtestService store latency and speed test results?

Results persist through `ProfileExManager.Instance.SetTestDelay` for latency values and `ProfileExManager.Instance.SetTestSpeed` for bandwidth values. This manager makes metrics available for UI display, server sorting, and selection algorithms throughout the v2rayN application.

### How does the bandwidth test avoid interfering with system proxy settings?

The service creates isolated `WebProxy` instances pointing to temporary local SOCKS5 listeners created specifically for each server test. This ensures bandwidth measurement occurs through dedicated proxy tunnels without modifying system-wide proxy configurations or affecting other applications.

### Can I customize the test URLs used by SpeedtestService?

Yes. Configure `_config.SpeedTestItem.SpeedPingTestUrl` for latency test targets and `_config.SpeedTestItem.SpeedTestUrl` for bandwidth test files in the v2rayN configuration settings. These URLs determine the destination endpoints used when measuring latency and download speed.