分类: C/C++
2009-02-19 16:22:27
#ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include #include #include #include #include #include #include #include #define MAX_BUFF_SIZE 256 struct net_stat { const char *dev; int up; long long last_read_recv, last_read_trans; //last read total num long long recv, trans; //real total num double recv_speed, trans_speed; }; /* network interface stuff */ static struct net_stat netstats[16]={0}; struct net_stat *get_net_stat(const char *dev) { unsigned int i=0; if (!dev) { return 0; } /* find interface stat */ for (i = 0; i < 16; i++) { if (netstats[i].dev && strcmp(netstats[i].dev, dev) == 0) { return &netstats[i]; } } /* wasn't found? add it */ if (i == 16) { for (i = 0; i < 16; i++) { if (netstats[i].dev == 0) { netstats[i].dev = strndup(dev, MAX_BUFF_SIZE); return &netstats[i]; } } } fprintf(stderr, "too many interfaces used (limit is 16)"); return 0; } void clear_net_stats(void) { memset(netstats, 0, sizeof(netstats)); } void update_net_stats(const char* dev, double delta) { FILE *net_dev_fp; // FIXME: arbitrary size chosen to keep code simple. int i=0; char buf[256]={0}; /* open file and ignore first two lines */ if (!(net_dev_fp = fopen("/proc/net/dev", "r"))) { fprintf(stderr, "fopen failed.\n"); clear_net_stats(); return; } fgets(buf, 255, net_dev_fp); /* garbage */ fgets(buf, 255, net_dev_fp); /* garbage (field names) */ /* read each interface */ for (i = 0; i < 16; i++) { struct net_stat *ns=NULL; unsigned char *s=NULL, *p=NULL; unsigned long long r=0, t=0; unsigned long long last_recv=0, last_trans=0; if (fgets(buf, 255, net_dev_fp) == NULL) { //File EOF break; } //Skip Space p = buf; while (isspace((int) *p)) { p++; } /*s: network interface name*/ s = p; //Skip Network Interface Name while (*p && *p != ':') { p++; } if (*p == '\0') { continue; } *p = '\0'; /*p: reveive bytes*/ p++; //Judge Network Interface or Not? if(strcmp(s, dev) != 0) continue; //Get struct net_stat ns = get_net_stat(s); ns->up = 1; last_recv = ns->recv; last_trans = ns->trans; /* bytes packets errs drop fifo frame compressed multicast|bytes ... */ sscanf(p, "%lld %*d %*d %*d %*d %*d %*d %*d %lld", &r, &t); /* if recv or trans is less than last time, an overflow happened */ if (r < ns->last_read_recv) { last_recv = 0; } else { ns->recv += (r - ns->last_read_recv); } ns->last_read_recv = r; if (t < ns->last_read_trans) { last_trans = 0; } else { ns->trans += (t - ns->last_read_trans); } ns->last_read_trans = t; /* calculate speeds */ if(last_recv == 0) ns->recv_speed = 0; else ns->recv_speed = (ns->recv - last_recv) / delta; if(last_trans == 0) ns->trans_speed = 0; else ns->trans_speed = (ns->trans - last_trans) / delta; /* //First Time Run, Or Time Overflow if(current_time == 0) { ns->recv_speed = 0; ns->trans_speed = 0; } */ //Find Network Interface, And Work Over break; } fclose(net_dev_fp); } int main() { int i=0; unsigned int sleep_time = 0; struct net_stat* ns = NULL; time_t current_time=0, last_time=0, delta_time=0; srand(time(NULL)); for(i=0; i<10000; i++) { last_time = current_time; current_time = time(NULL); delta_time = current_time-last_time; printf("Delta Time: %u Seconds\n", delta_time); update_net_stats("eth0", delta_time); ns = get_net_stat("eth0"); printf("Recv Speed: %f KB/s\n", ns->recv_speed/1024); printf("Send Speed: %f KB/s\n", ns->trans_speed/1024); sleep_time = 1+random()%5; printf("Sleep %d Second...\n", sleep_time); sleep(sleep_time); } return 0; } |