You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

C#实现Web服务连接测试(Ping、下载、上传)需求咨询

解决方案:Web服务定时监控(连接状态、Ping、上下行速度)

Hey Sebastian, let's work through this problem together—you're right that NetworkInterface isn't the right tool here because it's meant for managing local network hardware, not testing remote web services. Here's a straightforward, actionable plan to build your monitoring service:

核心思路

Instead of targeting network interfaces, we'll:

  1. Use scheduled tasks to run checks every minute
  2. Validate web service connectivity via HTTP requests
  3. Measure "ping" (TCP-based, no admin rights needed) or ICMP ping
  4. Test download/upload speeds by sending/receiving known-size data
  5. Store all metrics in your database for later analysis

Step 1: Set Up Scheduled Tasks

You'll need a way to trigger your monitoring logic every 60 seconds. Here are options for common languages:

  • Python: Use APScheduler (lightweight, easy to configure)
  • Java/Spring Boot: Use @Scheduled annotations
  • C#: Use Hangfire or System.Timers.Timer
  • Bash: Use cron jobs (for simple shell-script-based checks)

Step 2: Check Web Service Connectivity

First, add a dedicated health check endpoint to your web service (e.g., /health) that returns a 200 OK response when the service is up. This lets you quickly verify if the service is accepting connections.

For example, in Python with Flask:

@app.route('/health')
def health_check():
    return "OK", 200

In your monitoring service, send a GET request to this endpoint and check the status code. If it times out or returns a non-200 code, mark the service as unavailable.


Step 3: Measure Ping (TCP or ICMP)

ICMP ping often requires admin privileges, so TCP ping is more practical for web services. It works by timing how long it takes to establish a connection to your web service's port (80/443):

import time
import requests

def tcp_ping(url, timeout=5):
    try:
        start = time.time()
        requests.head(url, timeout=timeout)
        return round((time.time() - start) * 1000, 2)  # Convert to ms
    except Exception as e:
        return None  # Or raise an error

ICMP Ping (If You Have Permissions)

If you can run the monitoring service with admin rights, you can use ICMP ping for a more traditional network-level check:

import ping3

def icmp_ping(host):
    try:
        return round(ping3.ping(host), 2)  # Returns ms
    except Exception as e:
        return None

Step 4: Test Download & Upload Speeds

Download Speed

Request a fixed-size test file from your web service (e.g., a 5MB or 10MB static file) and calculate the speed based on transfer time:

def test_download_speed(url, timeout=10):
    try:
        start = time.time()
        response = requests.get(url, timeout=timeout)
        response.raise_for_status()
        file_size_bytes = len(response.content)
        elapsed_time = time.time() - start
        # Convert to kbps (kilobits per second)
        return round((file_size_bytes * 8) / (elapsed_time * 1024), 2)
    except Exception as e:
        return None

Upload Speed

Send a fixed-size payload to a dedicated upload test endpoint on your web service (this endpoint should just acknowledge receipt, no need to store the data):

def test_upload_speed(url, payload_size_mb=5, timeout=10):
    try:
        payload = b'X' * (payload_size_mb * 1024 * 1024)  # 5MB of dummy data
        start = time.time()
        response = requests.post(url, data=payload, timeout=timeout)
        response.raise_for_status()
        elapsed_time = time.time() - start
        # Convert to kbps
        return round((len(payload) * 8) / (elapsed_time * 1024), 2)
    except Exception as e:
        return None

Step 5: Store Metrics in Database

Create a table to store your monitoring logs (adjust schema to match your database):

CREATE TABLE service_monitor_logs (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
    status VARCHAR(20) NOT NULL, -- 'success' or 'failed'
    ping_ms REAL,
    download_speed_kbps REAL,
    upload_speed_kbps REAL,
    error_message TEXT
);

In your monitoring code, after collecting metrics, insert them into this table. Here's a Python example with SQLite (replace with your database driver):

import sqlite3

def save_to_db(metrics):
    conn = sqlite3.connect('monitor.db')
    cursor = conn.cursor()
    cursor.execute('''
        INSERT INTO service_monitor_logs 
        (status, ping_ms, download_speed_kbps, upload_speed_kbps, error_message)
        VALUES (?, ?, ?, ?, ?)
    ''', (
        metrics['status'],
        metrics['ping_ms'],
        metrics['download_speed_kbps'],
        metrics['upload_speed_kbps'],
        metrics['error_message']
    ))
    conn.commit()
    conn.close()

Full Example (Python)

Here's a complete, runnable example that ties everything together:

import time
import requests
import ping3
from apscheduler.schedulers.background import BackgroundScheduler
import sqlite3

# Configuration
WEB_SERVICE_BASE = "http://your-web-service-url"
HEALTH_ENDPOINT = f"{WEB_SERVICE_BASE}/health"
DOWNLOAD_TEST_FILE = f"{WEB_SERVICE_BASE}/test-5mb.bin"
UPLOAD_TEST_ENDPOINT = f"{WEB_SERVICE_BASE}/upload-test"

def init_db():
    conn = sqlite3.connect('monitor.db')
    cursor = conn.cursor()
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS service_monitor_logs (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
            status VARCHAR(20) NOT NULL,
            ping_ms REAL,
            download_speed_kbps REAL,
            upload_speed_kbps REAL,
            error_message TEXT
        )
    ''')
    conn.commit()
    conn.close()

def run_monitoring_check():
    metrics = {
        "status": "success",
        "ping_ms": None,
        "download_speed_kbps": None,
        "upload_speed_kbps": None,
        "error_message": None
    }

    # 1. TCP Ping
    try:
        metrics["ping_ms"] = tcp_ping(WEB_SERVICE_BASE)
        if metrics["ping_ms"] is None:
            raise Exception("TCP ping failed")
    except Exception as e:
        metrics["status"] = "failed"
        metrics["error_message"] = f"Ping error: {str(e)}"
        save_to_db(metrics)
        return

    # 2. Health Check
    try:
        response = requests.get(HEALTH_ENDPOINT, timeout=5)
        if response.status_code != 200:
            raise Exception(f"Health check returned {response.status_code}")
    except Exception as e:
        metrics["status"] = "failed"
        metrics["error_message"] = f"Health check error: {str(e)}"
        save_to_db(metrics)
        return

    # 3. Download Speed Test
    try:
        metrics["download_speed_kbps"] = test_download_speed(DOWNLOAD_TEST_FILE)
    except Exception as e:
        metrics["status"] = "failed"
        metrics["error_message"] = f"Download test error: {str(e)}"

    # 4. Upload Speed Test
    try:
        metrics["upload_speed_kbps"] = test_upload_speed(UPLOAD_TEST_ENDPOINT)
    except Exception as e:
        metrics["status"] = "failed"
        metrics["error_message"] = f"Upload test error: {str(e)}"

    # Save results
    save_to_db(metrics)
    print(f"Logged metrics: {metrics}")

# Helper functions (from earlier steps)
def tcp_ping(url, timeout=5):
    try:
        start = time.time()
        requests.head(url, timeout=timeout)
        return round((time.time() - start) * 1000, 2)
    except:
        return None

def test_download_speed(url, timeout=10):
    try:
        start = time.time()
        response = requests.get(url, timeout=timeout)
        response.raise_for_status()
        size = len(response.content)
        elapsed = time.time() - start
        return round((size * 8) / (elapsed * 1024), 2)
    except:
        return None

def test_upload_speed(url, payload_size_mb=5, timeout=10):
    try:
        payload = b'X' * (payload_size_mb * 1024 * 1024)
        start = time.time()
        response = requests.post(url, data=payload, timeout=timeout)
        response.raise_for_status()
        elapsed = time.time() - start
        return round((len(payload) * 8) / (elapsed * 1024), 2)
    except:
        return None

def save_to_db(metrics):
    conn = sqlite3.connect('monitor.db')
    cursor = conn.cursor()
    cursor.execute('''
        INSERT INTO service_monitor_logs 
        (status, ping_ms, download_speed_kbps, upload_speed_kbps, error_message)
        VALUES (?, ?, ?, ?, ?)
    ''', (
        metrics['status'],
        metrics['ping_ms'],
        metrics['download_speed_kbps'],
        metrics['upload_speed_kbps'],
        metrics['error_message']
    ))
    conn.commit()
    conn.close()

if __name__ == "__main__":
    init_db()
    scheduler = BackgroundScheduler()
    scheduler.add_job(run_monitoring_check, 'interval', minutes=1)
    scheduler.start()
    print("Monitoring service started. Press Ctrl+C to stop.")
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        scheduler.shutdown()
        print("Monitoring service stopped.")

Key Notes

  • Permissions: TCP ping works without admin rights; ICMP ping requires elevated privileges.
  • Endpoint Design: Use dedicated test endpoints to avoid impacting your web service's normal traffic.
  • Timeout Handling: Always add timeouts to your requests to prevent the monitoring task from hanging.
  • Resource Usage: Keep test file/payload sizes reasonable (1-10MB) to avoid consuming excessive bandwidth.
  • Deployment: Run the monitoring service as a background process (e.g., systemd service on Linux, Windows Service, or Docker container).

内容的提问来源于stack exchange,提问作者Sebastian

火山引擎 最新活动