【问题标题】:How do i monitor network traffic on Windows from the command line如何从命令行监视 Windows 上的网络流量
【发布时间】:2010-01-31 10:33:10
【问题描述】:

如何从命令行监控 Windows 上的网络流量;特别是下载/上传速度和上传/下载的数据量?是否有脚本/batch 可以做到这一点?

【问题讨论】:

  • 在Serverfault上问这个可能会更好
  • 我更新了我的答案以在 Windows 10 中工作并避免 32 位整数溢出。

标签: command-line network-programming monitoring


【解决方案1】:

虽然tshark 非常强大,如果您想获得细粒度的统计信息(根据主机、协议等),它的主要缺点是在运行期间收集统计信息。因此,它只擅长报告“即时”统计数据,而不是定期报告轮询流量,以了解您的网络流量在一天、一周内的变化情况......

此外,由于tshark 进行数据包捕获,因此存在一些开销。

因此,根据您的需要,您可能对 MS Windows netnetstat 命令感兴趣(netstat 可以选择按协议报告统计信息)。 'net statistics [Server|workstation]''netstat [-e|-s]' 是,就网络流量统计而言,Linux 'ifconfig'(或 'cat /proc/net/dev',如果您愿意)的 MS Windows 等效项。

请注意,正如ifconfig 所做的那样,netnetstat 仅报告自接口启动以来的数据量。

为了获得流量速率,您必须为对这些命令的调用添加时间戳并自己进行计算。

AFAIK,所有最新的 MS Windows 版本都附带了这两个命令。

【讨论】:

  • 我自己无法确认,但我读到如果您使用netstat -e 获取接收和发送的字节数,一旦发送或接收的数据达到 4GB,它就会重置两个计数器都归零。
【解决方案2】:

您可以将 tshark 与 -z <statistics> 参数一起使用。只需搜索Wireshark。它是开源和多平台的。

【讨论】:

    【解决方案3】:

    Windows 中的 typeperf 应该可以获取数据。

    typeperf "\Network Interface(*)\....
    typeperf -q "Network Interface" will list all the object
    \Network Interface(*)\Bytes Total/sec
    \Network Interface(*)\Packets/sec
    \Network Interface(*)\Packets Received/sec
    \Network Interface(*)\Packets Sent/sec
    \Network Interface(*)\Current Bandwidth
    \Network Interface(*)\Bytes Received/sec
    \Network Interface(*)\Packets Received Unicast/sec
    \Network Interface(*)\Packets Received Non-Unicast/sec
    \Network Interface(*)\Packets Received Discarded
    \Network Interface(*)\Packets Received Errors
    \Network Interface(*)\Packets Received Unknown
    \Network Interface(*)\Bytes Sent/sec
    \Network Interface(*)\Packets Sent Unicast/sec
    \Network Interface(*)\Packets Sent Non-Unicast/sec
    \Network Interface(*)\Packets Outbound Discarded
    \Network Interface(*)\Packets Outbound Errors
    \Network Interface(*)\Output Queue Length
    \Network Interface(*)\Offloaded Connections
    

    【讨论】:

    • 这个答案帮助我完成了我的公式 Nic Utilization = ((Total Bytes\Sec * 8)/current bandwidth) * 100
    【解决方案4】:

    我正在更新答案以获得更完整的准确答案,使用netsh 命令和一些字符串操作以避免Windows 32 位整数溢出

    记住您需要运行netsh interface ip show subinterfaces 并检查您的网络适配器的线路。以下批处理文件使用第 4 个字符串行,即列出的第一个适配器。

    它每 10 秒检查一次速度。如果您的上传或下载速度高达每秒 100 MB,则需要更频繁地重复循环(例如每 1 秒)。

    它也会创建一个 .csv 文件。如果不需要,请删除最后一行。

    批处理文件:

    @ECHO off
    SETLOCAL ENABLEDELAYEDEXPANSION
    
    set TAB=    
    echo Timestamp%TAB%Down bytes%TAB%Up bytes%TAB%Down speed%TAB%Up speed
    
    :looptask
    
    :: Store console command result
    SET count=1
    ::FOR /F "tokens=* USEBACKQ" %%F IN (`netstat -e`) DO (
    FOR /F "tokens=* USEBACKQ" %%F IN (`netsh interface ip show subinterfaces`) DO (
      SET string!count!=%%F
      SET /a count=!count!+1
    )
    
    :: *** Change string number to the line with your interface data ***
    set line=%string4%
    :: For ME, bytes transfered line is string3 using netstat and string4 using netsh
    
    :: Get rid of the whitespaces 
    :loopreplace
    if defined line (
      set "new=!line:  = !"
      if "!new!" neq "!line!" (
        set "line=!new!"
        goto :loopreplace
      )
    )
    if defined line if "!line:~0,1!" equ " " set "line=!line:~1!"
    if defined line if "!line:~-1!" equ " " set "line=!line:~0,-1!"
    
    :: Extracting bytes downloaded and uploaded
    ::FOR /F "tokens=2,3 delims= " %%A IN ("%line%") DO (
    FOR /F "tokens=3,4 delims= " %%A IN ("%line%") DO (
      set dbytes=%%~A
      set ubytes=%%~B
    )
    
    :: Midnight epoch
    for /F "usebackq tokens=1,2 delims==" %%i in (`wmic os get LocalDateTime /VALUE 2^>NUL`) do if '.%%i.'=='.LocalDateTime.' set ldt=%%j
    set time=%ldt:~8,2%:%ldt:~10,2%:%ldt:~12,2%
    FOR /F "tokens=* delims=0" %%A IN ("%ldt:~8,2%") DO SET /A hs=%%A+0
    FOR /F "tokens=* delims=0" %%A IN ("%ldt:~10,2%") DO SET /A min=%%A+0
    FOR /F "tokens=* delims=0" %%A IN ("%ldt:~12,2%") DO SET /A sec=%%A+0
    set /a epoch=%hs%*3600+%min%*60+%sec%
    
    :: Calc initial transfer
    if not defined LOOPCOMPLETE (
        echo %time%%TAB%%dbytes%%TAB%%ubytes%%TAB%0.00 KB/s%TAB%0.00 KB/s
        goto :skip
    )
    :: Read .CSV file last line values
    for /f %%i in ('find /v /c "" ^< bwlog.csv') do set /a lines=%%i
    set /a lastLine=%lines% - 1
    SET count=1
    FOR /F "tokens=* USEBACKQ" %%F IN (`more /e +%lastLine% bwlog.csv`) DO (
      SET string!count!=%%F
      SET /a count=!count!+1
    )
    FOR /F "tokens=1,2,3 delims=," %%A IN ("%string1%") DO (
      set lasttime=%%~A
      set lastdown=%%~B
      set lastup=%%~C
    )
    if %epoch% == %lasttime% (  
        goto :skip
    )
    
    :: 2,147,483,647 is the maximum value of a integer you can use, so only keep  9 characters
    set /a lastup=%lastup: =%
    set /a ddif=%dbytes:~-9% - %lastdown:~-9%
    set /a udif=%ubytes:~-9% - %lastup:~-9%
    
    :: Calc bandwidth
    set /a dspeed=(ddif)/(epoch-lasttime)/10
    set ddec=%dspeed:~-2%
    set /a dspeed=(ddif)/(epoch-lasttime)/1000
    set /a uspeed=(udif)/(epoch-lasttime)/10
    set udec=%uspeed:~-2%
    set /a uspeed=(udif)/(epoch-lasttime)/1000
    echo %time%%TAB%%dbytes%%TAB%%ubytes%%TAB%%dspeed%.%ddec% KB/s%TAB%%uspeed%.%udec% KB/s
    
    :skip
    
    :: Append the .CSV file 
    echo %epoch%,%dbytes%,%ubytes% >> "bwlog.csv"
    
    :: Do every 10 seconds
    set LOOPCOMPLETE=1
    timeout /t 10 /nobreak >nul
    goto :looptask
    
    ENDLOCAL
    

    如果您需要修复,请保持联系。


    以前使用批处理文件的解决方案,有一些限制:

    我想给你一个更简单的解决方案,然后我使用我之前的答案编写了一个新的 Windows 批处理脚本,该脚本每 10 秒迭代一次。它在控制台中监控下载和上传带宽/速度,并在 .csv 文件中记录传输的字节数。

    @ECHO off
    SETLOCAL ENABLEDELAYEDEXPANSION
    
    set TAB=    
    echo Timestamp%TAB%Down bytes%TAB%Up bytes%TAB%Down speed%TAB%Up speed
    
    :: Store console command result
    :looptask
    SET count=1
    FOR /F "tokens=* USEBACKQ" %%F IN (`netstat -e`) DO (
      SET string!count!=%%F
      SET /a count=!count!+1
    )
    :: Bytes transfered line is string3
    
    :: Get rid of the whitespaces 
    :loopreplace
    if defined string3 (
      set "new=!string3:  = !"
      if "!new!" neq "!string3!" (
        set "string3=!new!"
        goto :loopreplace
      )
    )
    if defined string3 if "!string3:~0,1!" equ " " set "string3=!string3:~1!"
    if defined string3 if "!string3:~-1!" equ " " set "string3=!string3:~0,-1!"
    
    :: Extracting bytes downloaded and uploaded
    set line=%string3:~6%
    FOR /F "tokens=1,2 delims= " %%A IN ("%line%") DO (
      set dbytes=%%~A
      set ubytes=%%~B
    )
    
    :: Midnight epoch
    for /F "usebackq tokens=1,2 delims==" %%i in (`wmic os get LocalDateTime /VALUE 2^>NUL`) do if '.%%i.'=='.LocalDateTime.' set ldt=%%j
    set time=%ldt:~8,2%:%ldt:~10,2%:%ldt:~12,2%
    FOR /F "tokens=* delims=0" %%A IN ("%ldt:~8,2%") DO SET /A hs=%%A+0
    FOR /F "tokens=* delims=0" %%A IN ("%ldt:~10,2%") DO SET /A min=%%A+0
    FOR /F "tokens=* delims=0" %%A IN ("%ldt:~12,2%") DO SET /A sec=%%A+0
    set /a epoch=%hs%*3600+%min%*60+%sec%
    
    :: Calc speeds
    if not defined LOOPCOMPLETE (
        echo %time%%TAB%%dbytes%%TAB%%ubytes%%TAB%0.00 KB/s%TAB%0.00 KB/s
        goto :skip
    )
    :: Read .CSV file last line values
    for /f %%i in ('find /v /c "" ^< bwlog.csv') do set /a lines=%%i
    set /a lastLine=%lines% - 1
    SET count=1
    FOR /F "tokens=* USEBACKQ" %%F IN (`more /e +%lastLine% bwlog.csv`) DO (
      SET string!count!=%%F
      SET /a count=!count!+1
    )
    FOR /F "tokens=1,2,3 delims=," %%A IN ("%string1%") DO (
      set lasttime=%%~A
      set lastdown=%%~B
      set lastup=%%~C
    )
    if %epoch% == %lasttime% (  
        goto :skip
    )
    set /a dspeed=(dbytes-lastdown)/(epoch-lasttime)/10
    set ddec=%dspeed:~-2%
    set /a dspeed=(dbytes-lastdown)/(epoch-lasttime)/1000
    set /a uspeed=(ubytes-lastup)/(epoch-lasttime)/10
    set udec=%dspeed:~-2%
    set /a uspeed=(ubytes-lastup)/(epoch-lasttime)/1000
    echo %time%%TAB%%dbytes%%TAB%%ubytes%%TAB%%dspeed%.%ddec% KB/s%TAB%%uspeed%.%udec% KB/s
    :skip
    
    :: Append the .CSV file 
    echo %epoch%,%dbytes%,%ubytes% >> "bwlog.csv"
    
    :: Do every 10 seconds
    set LOOPCOMPLETE=1
    timeout /t 10 /nobreak >nul
    goto :looptask
    
    ENDLOCAL
    

    PS:Windows 限制是每传输 4GBytes 并在午夜重置计数器。


    使用任务调度器和 XAMPP 的旧解决方案:

    根据您的情况,我必须监控和记录下载的数据量,并发现使用 Windows 任务调度程序运行脚本比寻找免费的要快将常用图形信息转储到文件中的软件。也许我的自制脚本适合你。

    我使用XAMPP for Windows 启动了一个本地 Apache/PHP 服务器并从命令行运行此脚本。例如:

    "C:\xampp\php\php.exe -f C:\xampp\htdocs\bwlog.php"
    

    bwlog.php 脚本使用 @phep answer 建议的 windows 命令 netstat -e。可以用记事本创建脚本文件,代码为:

    <?php
    //Task to schedule "C:\xampp\php\php.exe -f C:\xampp\htdocs\bwlog.php"
    //Store console command result
    $netstat=shell_exec("netstat -e");
    //Start of the bytes transfered line
    $line=substr($netstat,strpos($netstat,"Bytes"));    
    //End of the line
    $line=substr($line,0,strpos($line,"\n"));   
    //Get rid of the whitespaces 
    $bytes=preg_replace('/\s+/', ' ',$line);    
    //Extracting only bytes downloaded
    $bytes=substr($bytes,$start=strpos($bytes,' ')+1,strrpos($bytes,' ')-$start);
    //Append the .CSV file  
    file_put_contents('C:\xampp\htdocs\bwlog.csv',PHP_EOL.time().', '.$bytes,FILE_APPEND);
    ?>
    

    然后我在电子表格软件中处理 .csv 以计算 下载速度(带宽)使用 2 个字节值之间的差异超过 2 个匹配之间的差异时间值(字节/秒)。

    随时请求修复以记录上传的字节。希望有用。

    【讨论】:

    • 我有一个使用netsh interface ip show subinterfaces 的新版本,可能更准确。随时要求。
    • 嗨,Leopoldo,有什么变化吗?我在 Windows10 上试过这个。上传作品,但不下载。
    • @Skuta 感谢您的评论。我在 Windows 10 中测试了脚本。我发现 Windows 对整数大小有限制。因此,如果您的上传或下载足够大,则尝试将字符串转换为数字将失败。我修复了它,并使用netsh 命令更新了答案以获得更准确的测量。试一试,随时询问是否需要其他修复。
    猜你喜欢
    • 2011-12-29
    • 2012-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-17
    • 2021-10-06
    • 1970-01-01
    相关资源
    最近更新 更多