【发布时间】:2017-04-06 01:46:37
【问题描述】:
我有一个 HTTP 线程代理,即对于来自客户端的每个请求,我都会生成一个线程:现在我想收集一些统计信息,例如每秒比特数 (bps) 和每秒数据包数 (pps)。
我喜欢我的代码只做一件事,所以如果一个线程处理一个连接,它也不会为每个数据包计算 bps 和 pps,我将把它留给另一个线程。
我为来自客户端的每个 HTTP 请求创建一个线程,如果代理成功连接到请求的远程服务器,proxt 将实际的 HTTP 请求发送到服务器,在路由数据之前,连接线程创建一个日志线程:日志线程将计算 bps 和 pps 直到连接打开。连接线程向日志线程提供有关过滤哪些数据包的信息(本地 IP 地址、本地端口、远程 IP 地址、远程端口),因此每个日志线程将仅过滤来自父连接线程的数据包。
我在为每个数据包计算 bps 和 pps 时遇到问题。
这是我在日志线程中循环捕获数据包的伪代码:
// pcap variables
pcap_t *handle;
struct pcap_pkthdr *header;
const u_char *pkt_data;
// timevals used to calculate delay from last filtered packet
struct timeval oldTimevalUpload;
struct timeval oldTimevalDownload;
memset(&oldTimevalUpload, 0, sizeof(oldTimevalUpload));
memset(&oldTimevalDownload, 0, sizeof(oldTimevalDownload));
// stopLogging is a boolean flag declared in connection "parent" thread:
// it is set to false when connection thread has done sending and
// receiving data and connection is going to be closed
while (((res = pcap_next_ex(handle, &header, &pkt_data)) >= 0) && (!stopLogging)) {
// check res
if (packet is upload) {
struct timeval difference;
timeval_subtract(&difference, &(header->ts), &oldTimevalUpload);
long long delay = (difference.tv_sec * 1000000) + difference.tv_usec;
long long acceptedPackets = ((long long)(pkt_data)) * 1000000;
long long acceptedBits = ((long long)(pkt_data+8)) * 8 * 1000000;
long long pps = acceptedPackets / delay;
long long bps = acceptedBits / delay;
debugRed(host << ", UPLOAD DIVIDE ACCEPTED PKTS " << acceptedPackets <<
" AND ACCEPTED BITS " << acceptedBits << " PER DELAY " << delay <<
" IS PPS " << pps << " AND BPS " << bps);
oldTimevalUpload.tv_sec = header->ts.tv_sec;
oldTimevalUpload.tv_usec = header->ts.tv_usec;
} else if (packet is download) {
// basically the same as above
}
}
debug("Quit logging connection " << localIPaddr << ":" << localPort << " and "
<< remoteIPaddr << ":" << remotePort);
pcap_close(handle);
这是一个示例输出:
www.netflix.com UPLOAD, DIVIDE ACCEPTED PKTS 99239440000000 AND ACCEPTED BITS 793915584000000 PER DELAY 1479811349890053 IS PPS 0 AND BPS 0
www.netflix.com DOWNLOAD, DIVIDE ACCEPTED PKTS 99239440000000 AND ACCEPTED BITS 793915584000000 PER DELAY 1479811350032141 IS PPS 0 AND BPS 0
www.netflix.com DOWNLOAD, DIVIDE ACCEPTED PKTS 99239440000000 AND ACCEPTED BITS 793915584000000 PER DELAY 4344 IS PPS 22845174953 AND BPS 182761414364
www.netflix.com UPLOAD, DIVIDE ACCEPTED PKTS 99239440000000 AND ACCEPTED BITS 793915584000000 PER DELAY 146464 IS PPS 677568822 AND BPS 5420551015
www.netflix.com DOWNLOAD, DIVIDE ACCEPTED PKTS 99239440000000 AND ACCEPTED BITS 793915584000000 PER DELAY 2815 IS PPS 35253797513 AND BPS 282030402841
www.netflix.com UPLOAD, DIVIDE ACCEPTED PKTS 99239440000000 AND ACCEPTED BITS 793915584000000 PER DELAY 2808 IS PPS 35341680911 AND BPS 282733470085
www.netflix.com DOWNLOAD, DIVIDE ACCEPTED PKTS 99239440000000 AND ACCEPTED BITS 793915584000000 PER DELAY 1120 IS PPS 88606642857 AND BPS 708853200000
www.netflix.com UPLOAD, DIVIDE ACCEPTED PKTS 99239440000000 AND ACCEPTED BITS 793915584000000 PER DELAY 1134 IS PPS 87512733686 AND BPS 700101925925
www.netflix.com UPLOAD, DIVIDE ACCEPTED PKTS 99239440000000 AND ACCEPTED BITS 793915584000000 PER DELAY 39658 IS PPS 2502381360 AND BPS 20019052498
www.netflix.com DOWNLOAD, DIVIDE ACCEPTED PKTS 99239440000000 AND ACCEPTED BITS 793915584000000 PER DELAY 176317 IS PPS 562846690 AND BPS 4502773890
www.netflix.com UPLOAD, DIVIDE ACCEPTED PKTS 99239440000000 AND ACCEPTED BITS 793915584000000 PER DELAY 136687 IS PPS 726034224 AND BPS 5808274261
我从来不知道我的家庭网络可以承受超过 500 MBps 的速度,所以肯定有问题。
This page 展示了如何计算 bps 和 pps 并解释了 8 chars 在 acceptedBits 中的变化,但无论如何我都会报告它。这里可以看到函数pcap_next_ex的第二个和第三个参数:
基本上,他说的我都做了!为什么我的 bps 和 pps 变得如此庞大和奇怪?
在 Ubuntu 14.04 上工作;不知道如何检查libpcap 版本,但locate libpcap 给出了这个:
/home/dexter/Desktop/wireshark-1.99.9/wiretap/libpcap.c
/home/dexter/Desktop/wireshark-1.99.9/wiretap/libpcap.h
/usr/lib/x86_64-linux-gnu/libpcap.a
/usr/lib/x86_64-linux-gnu/libpcap.so
/usr/lib/x86_64-linux-gnu/libpcap.so.0.8
/usr/lib/x86_64-linux-gnu/libpcap.so.1.5.3
/usr/share/doc/libpcap-dev
/usr/share/doc/libpcap0.8
/usr/share/doc/libpcap0.8-dev
/usr/share/doc/libpcap-dev/changelog.Debian.gz
/usr/share/doc/libpcap-dev/copyright
/usr/share/doc/libpcap0.8/CREDITS.gz
/usr/share/doc/libpcap0.8/README.Debian
/usr/share/doc/libpcap0.8/README.gz
/usr/share/doc/libpcap0.8/changelog.Debian.gz
/usr/share/doc/libpcap0.8/copyright
/usr/share/doc/libpcap0.8-dev/changelog.Debian.gz
/usr/share/doc/libpcap0.8-dev/copyright
/var/lib/dpkg/info/libpcap-dev.[list,md5sums]
/var/lib/dpkg/info/libpcap0.8-dev.[list,md5sums,preinst]
/var/lib/dpkg/info/libpcap0.8:amd64.[list,md5sums,postinst,postrm,shlibs,symbols]
【问题讨论】:
标签: c++ multithreading c++11 http-proxy libpcap