如何在 Linux 中获取特定端口或应用程序进程 ID 的 KB/MB/Bytes 格式的实时网络统计信息?

如何在 Linux 中获取特定端口或应用程序进程 ID 的 KB/MB/Bytes 格式的实时网络统计信息?

我使用了IPTraf、、、、。它们都无法帮助我找到以 KBIftop或MB 格式从我的应用程序发送/接收的实时vnstat数据包。原因是我正在编写一个应用程序,我需要非常确定我的压缩是正确的,但我无法进行测试以继续前进。bwm-ngifconfig -a

我可以使用什么来跟踪非常具体和准确的实时网络统计数据?

在此处输入图片描述

答案1

您的应用程序可能正在将数据包发送到特定的 UDP 或 TCP 端口号或特定的 IP 地址。

因此,您可以使用 TCPdump 之类的工具来捕获该流量。

TCPdump 不会提供您想要的实时统计数据,但您可以将它的输出提供给提供该统计数据的程序(我将尝试稍后用答案更新这个答案)。


更新:

$ sudo tcpdump -i eth1 -l -e -n | ./netbps
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 96 bytes
11:36:53    2143.33 Bps
11:37:03    1995.99 Bps
11:37:13    2008.35 Bps
11:37:23    1999.97 Bps
11:37:33    2083.32 Bps
131 packets captured
131 packets received by filter
0 packets dropped by kernel

一分钟后,我按下 Ctrl+C 来中断它。

您需要在命令末尾添加合适的过滤表达式,tcpdump以仅包含您的应用生成的流量(例如port 123

该程序netbps是这样的:

#!/usr/bin/perl
use strict;
use warnings;
use Time::HiRes;

my $reporting_interval = 10.0; # seconds
my $bytes_this_interval = 0;
my $start_time = [Time::HiRes::gettimeofday()];

STDOUT->autoflush(1);

while (<>) {
  if (/ length (\d+):/) {
    $bytes_this_interval += $1;
    my $elapsed_seconds = Time::HiRes::tv_interval($start_time);
    if ($elapsed_seconds > $reporting_interval) {
       my $bps = $bytes_this_interval / $elapsed_seconds;
       printf "%02d:%02d:%02d %10.2f Bps\n", (localtime())[2,1,0],$bps;
       $start_time = [Time::HiRes::gettimeofday()];
       $bytes_this_interval = 0;
    }
  }
}

这只是一个例子,请根据口味进行调整。

答案2

同一文件夹中的使用方法如下:

检查每个接口的打包程序:./netpps.sh eth0

要检查每个接口的速度:./netspeed.sh eth0

测量接口上的每秒数据包数网络pps工具作为文件名

#!/bin/bash

INTERVAL="1"  # update interval in seconds

if [ -z "$1" ]; then
        echo
        echo usage: $0 [network-interface]
        echo
        echo e.g. $0 eth0
        echo
        echo shows packets-per-second
        exit
fi

IF=$1

while true
do
        R1=`cat /sys/class/net/$1/statistics/rx_packets`
        T1=`cat /sys/class/net/$1/statistics/tx_packets`
        sleep $INTERVAL
        R2=`cat /sys/class/net/$1/statistics/rx_packets`
        T2=`cat /sys/class/net/$1/statistics/tx_packets`
        TXPPS=`expr $T2 - $T1`
        RXPPS=`expr $R2 - $R1`
        echo "TX $1: $TXPPS pkts/s RX $1: $RXPPS pkts/s"
done

测量接口上的网络带宽网速工具作为文件名

#!/bin/bash

INTERVAL="1"  # update interval in seconds

if [ -z "$1" ]; then
        echo
        echo usage: $0 [network-interface]
        echo
        echo e.g. $0 eth0
        echo
        exit
fi

IF=$1

while true
do
        R1=`cat /sys/class/net/$1/statistics/rx_bytes`
        T1=`cat /sys/class/net/$1/statistics/tx_bytes`
        sleep $INTERVAL
        R2=`cat /sys/class/net/$1/statistics/rx_bytes`
        T2=`cat /sys/class/net/$1/statistics/tx_bytes`
        TBPS=`expr $T2 - $T1`
        RBPS=`expr $R2 - $R1`
        TKBPS=`expr $TBPS / 1024`
        RKBPS=`expr $RBPS / 1024`
        echo "TX $1: $TKBPS kB/s RX $1: $RKBPS kB/s"
done

请参阅此网站了解更多信息http://xmodulo.com/measure-packets-per-second-throughput-high-speed-network-interface.html

答案3

最容易使用和最容易控制输出并重定向到文件进行连续记录:

ifstat

可能与大多数 Linux 发行版一起提供,并且可以在 Mac 上使用 brew 安装

答案4

我只需要测量在 perl 无法正常工作的旧系统上有多少 mysql 流量进出,因此我忍不住写了几行 awk 来实现同样的目的,即测量 tcpdump 看到的总流量:

# tcpdump -l -e -n port 3306 | \
  awk '{
  t=substr($1, 0, 8);
  n=substr($9, 0, length($9)-1);
  if(t != pt){
    print t, sum;
    sum = 0;
  } else {
    sum += n
  }
  pt=t;
}'

tcpdump: WARNING: eth0: no IPv4 address assigned
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
14:41:54 
14:41:55 466905
14:41:56 765220
14:41:57 741511
14:41:58 688219
14:41:59 492322
14:42:00 800087
14:42:01 1248608
14:42:02 1276476
14:42:03 755586
14:42:04 1029453
14:42:05 818298
^C32515 packets captured
32633 packets received by filter
107 packets dropped by kernel

如果你更喜欢单行代码,这里有一个适合你:

tcpdump -l -e -n port 3306 | awk '{t=substr($1,0,8);n=substr($9,0,length($9)-1);if(t!=pt){print t,sum;sum=0;}else{sum+=n}pt=t;}'

相关内容