Under Windows, we can see 360 or QQ Security defender's "safety ball", which shows the real-time speed situation. So how to get the real-time speed of network card in Linux? In fact, the principle is very simple, read the network card needs to obtain the speed of a certain period of time in the DT traffic changes DL, then the real-time speed is coming out, fast = Dl/dt.
Linux provides functions in Ifaddrs.h:
/* Create A linked list of ' struct IFADDRS ' structures, one for each network interface on the host machine. If successful, store the list in *IFAP and return 0. On errors, return-1 and set ' errno '. The storage returned in *IFAP are allocated dynamically and can only being properly freed by passing it to ' Freeifaddrs '. C6/>*/extern int Getifaddrs (struct Ifaddrs **__ifap) __throw; /* Reclaim the storage allocated by a previous ' Getifaddrs ' call. */extern void Freeifaddrs (struct Ifaddrs *__ifa) __throw;
The system will create a list of all the network card information in this machine, and then we can get the information we want in this list.
/* the ' Getifaddrs ' function generates a linked list of these structures. Each element of the list describes one network interface. */struct ifaddrs{struct Ifaddrs *ifa_next;/* Pointer to the next structure. */char *ifa_name; /* Name of this network interface. */unsigned int ifa_flags; /* Flags as from Siocgifflags IOCTL. */struct SOCKADDR *ifa_addr; /* Network address of this interface. */struct SOCKADDR *ifa_netmask; /* Netmask of this interface. */Union {/* at most one of the following are valid. If the Iff_broadcast bit is set in ' Ifa_flags ' and then ' ifa_broadaddr ' is valid. If the Iff_pointopoint bit is set and then ' IFA_DSTADDR ' is valid. It is never, the case, both these bits is set at once. */struct SOCKADDR *ifu_broadaddr; /* Broadcast address of this interface. */struct SOCKADDR *ifu_dstaddr; /* Point-to-Point Destination address. */} Ifa_ifu; /* These very same macros is defined by <net/if.h> for' struct ifaddr '. So if they is defined already, the existing definitions would be fine. */# ifndef ifa_broadaddr# define IFA_BROADADDR ifa_ifu.ifu_broadaddr# endif# ifndef ifa_dstaddr# define IFA_DSTADDR if a_ifu.ifu_dstaddr# endif void *ifa_data; /* address-specific data (may be unused). */};
In addition, this list can be pre-selected with the IOCTL, can be determined by ifa_name and ifa_flags to determine the Ifa_ifu inside the union. But this time we are here to measure the real-time speed of the network, do not need to care.
We need to care about is ifa_data this item, about this item I Baidu a lot, has not found that he should belong to which structure body.
Later inadvertently found in the http://blog.chinaunix.net/uid-22832715-id-292763.html have similar, but I can not find the head file in there, so I just put him directly into my head file;
struct if_data{/* generic interface Information */u_charifi_type;/* ethernet, tokenring, etc */u_charifi_addrlen;/* Media address length */u_charifi_hdrlen;/* media header length */u_longifi_mtu;/* Maximum transmission unit */u_longifi_m etric;/* Routing Metric (external only) */u_longifi_baudrate;/* LineSpeed *//* volatile Statistics */u_longifi_ipackets ;/* Packets received on interface */u_longifi_ierrors;/* input errors on interface */u_longifi_opackets;/* packets sent on Interface */u_longifi_oerrors;/* output errors on interface */u_longifi_collisions;/* collisions on CSMA interfaces */u_l ongifi_ibytes;/* total number of octets received */u_longifi_obytes;/* total number of octets sent */u_longifi_imcasts;/* Packets received via multicast */u_longifi_omcasts;/* packets sent via multicast */u_longifi_iqdrops;/* dropped on input, This interface */u_longifi_noproto;/* destined for unsupported protocol */structtimeval ifi_lastchange;/* Last updated */ };
I have just started to print the Ifi_iobytes,ifi_obytes two items, no matter how I download and last file, both of them are 0. Tangled up my half-day, I will directly print out all the variables, found ifi_mtu,ifi_metric,ifi_baudrate and ifconfig eth0 output data very much like.
[15:12 @ ~/program/netspeed]$ ifconfig eth0eth0 Link encap:ethernet HWaddr 00:22:15:67:f8:16 inet addr : 210.42.158.204 bcast:210.42.158.255 mask:255.255.255.0 inet6 addr:fe80::222:15ff:fe67:f816/64 Scope : Link up broadcast RUNNING multicast mtu:1500 metric:1 RX packets:917978 errors:0 dropped:0 Overruns : 0 frame:0 TX packets:1132894 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:132866544 (126.7 MiB) TX bytes:1250785627 (1.1 GiB)
Slowly I know the law, struct Ifaddrs inside of Ifa_data first four words (32 bits) in this is the number of packets sent, the number of packets received, the number of bytes sent, the number of bytes received.
I re-tuned the struct if_data structure, and since the data is all 0, I've kept 4 items:
struct if_data{/ * Generic interface information */ u_long ifi_opackets; /* packets sent on interface */ u_long ifi_ipackets; /* packets received on interface */ u_long ifi_obytes; /* Total number of octets sent */ u_long ifi_ibytes; /* Total number of octets received */};
Test OK.
[15:17 @ ~/program/netspeed]$./netspeed Get eth0 Speed
Attach the code I have encapsulated:
int get_if_dbytes (struct if_info* ndev) {assert (Ndev); struct Ifaddrs *ifa_list = NULL; struct Ifaddrs *ifa = NULL; struct If_data *ifd = NULL; int ret = 0; ret = Getifaddrs (&ifa_list); if (Ret < 0) {perror ("Get Interface Address Fail:"); Goto end; } for (ifa=ifa_list; ifa; ifa=ifa->ifa_next) {if (!) ( Ifa->ifa_flags & iff_up) &&! (Ifa->ifa_flags & Iff_running)) Continue if (Ifa->ifa_data = = 0) continue; ret = strcmp (ifa->ifa_name,ndev->ifi_name); if (ret = = 0) {ifd = (struct If_data *) ifa->ifa_data; Ndev->ifi_ibytes = ifd->ifi_ibytes; Ndev->ifi_obytes = ifd->ifi_obytes; Break }} Freeifaddrs (Ifa_list); End:return (ret -1:0);} int get_if_speed (struct if_speed *ndev) {assert (Ndev); struct If_info *p1=null,*p2=null; P1 = (struct If_info *)malloc (sizeof (struct if_info)); P2 = (struct If_info *) malloc (sizeof (struct if_info)); Bzero (p1,sizeof (struct if_info)); Bzero (p2,sizeof (struct if_info)); strncpy (P1->ifi_name,ndev->ifs_name,strlen (ndev->ifs_name)); strncpy (P2->ifi_name,ndev->ifs_name,strlen (ndev->ifs_name)); int ret = 0; ret = Get_if_dbytes (p1); if (Ret < 0) goto end; Usleep (Ndev->ifs_us); ret = Get_if_dbytes (p2); if (Ret < 0) goto end; Ndev->ifs_ispeed = p2->ifi_ibytes-p1->ifi_ibytes; Ndev->ifs_ospeed = P2->ifi_obytes-p1->ifi_obytes;end:free (p1); Free (p2); return 0;}
Header file:
#ifndef __tspeed_h__#define __tspeed_h__#ifdef __cplusplusextern "C" {#endif #include <stdio.h> #include < stdlib.h> #include <string.h> #include <assert.h> #include <error.h>/* for "open" function */#inclu De <sys/types.h> #include <sys/stat.h> #include <fcntl.h>struct if_data{/* Generic interface Infor mation */U_long ifi_opackets; /* Packets sent on interface */U_long ifi_ipackets; /* Packets Received on interface */U_long ifi_obytes; /* Total number of octets sent */U_long ifi_ibytes; /* Total number of octets received */}; struct if_info{char ifi_name[16]; unsigned long ifi_ibytes; unsigned long ifi_obytes;}; struct if_speed{char ifs_name[16]; unsigned long ifs_ispeed; unsigned long ifs_ospeed; unsigned long ifs_us;}; extern int get_if_dbytes (struct if_info *ndev), extern int get_if_speed (struct if_speed *ndev), #ifdef __cplusplus} #endif #endif
Test code:
int main (int argc, char **argv) { struct if_speed ndev; int ret = 0; Bzero (&ndev,sizeof (Ndev)); sprintf (Ndev.ifs_name, "eth0"); Ndev.ifs_us = 100000; printf ("Get%s speed"); ret = Get_if_speed (&ndev); if (Ret < 0) printf ("\t\t\t[fail]\n"); else printf ("\t\t\t[ok]\n"); float ispeed, ospeed; while (1) { ispeed = ndev.ifs_ispeed * 1.0/(ndev.ifs_us/1000 * 0.001); Ospeed = Ndev.ifs_ospeed * 1.0/(ndev.ifs_us/1000 * 0.001); printf ("%s:up Speed:%f MB/s | | Down speed:%f mb/s \ r ", ndev.ifs_name,ispeed/(1024.0*1024.0), ospeed/(1024.0*1024.0)); Get_if_speed (&ndev); } return 0;} /*-----End of Main ()-----*/
Maybe you have a better way to get the speed of the message!
"Linux environment Programming" get the real-time speed of network card