unix socket实现网卡接口多线程监控 rx_packets, tx_packets, rx_errs, tx_errs等数据

废话不多说,直接上代码:

客户端:

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/un.h>
#include <string.h>
#include <stdio.h>
#include <ifaddrs.h>
#include <sys/ioctl.h>
#include <iostream>
#include <net/if.h>
#include <net/if_arp.h> 


using namespace std;

#define PORT  8890
#define BUFFER_SIZE 1024
#define MAXINTERFACES 64 
const char *filename="/tmp/sss";

 
struct net{
    char name[128];
    char mac[30];
    char ip[30];
    char state[30];
    unsigned long long rx_bytes;
    unsigned long long rx_packets;
    unsigned long long rx_errs;
    unsigned long long rx_drop;
    
    unsigned long long tx_bytes;
    unsigned long long tx_packets;
    unsigned long long tx_errs;
    unsigned long long tx_drop;
};
 
enum if_item
{
    RX_BYTES = 0,
    RX_PACKETS,
    RX_ERRS,
    RX_DROP,
    RX_FIFO,
    RX_FRAME,
    RX_COMPRESSED,
    RX_MULTICAST,
    TX_BYTES,
    TX_PACKETS,
    TX_ERRS,
    TX_DROP,
    TX_FIFO,
    TX_COLLS,
    TX_CARRIER,
    TX_COMPRESSED,
    IF_ITEM_MAX
};

int AdapterCount(struct net* Adapter)
{
    int nCount=0;
    FILE* fp = fopen("/proc/net/dev", "r");
    if(!fp)
    {
        perror("fopen /proc/net/dev");
        exit(0);
    }
    char szline[1024] = {0};
    fgets(szline, sizeof(szline), fp);
    fgets(szline, sizeof(szline), fp);
 
    int i=0;
    struct ifreq ifr_mac_ip;
    int s = socket(AF_UNIX, SOCK_STREAM, 0);
    memset(szline, 0, sizeof(szline));
    //
    while(fgets(szline, sizeof(szline), fp) != NULL)
    {
        //
        string name = szline;
        int p1 = name.find_first_of(':', 0);
        name = name.substr(0, p1);
        int p2 = name.rfind(' ', -1);
        if(p2 != -1)
        {
            name = name.substr(p2+1, -1);
        }
        memcpy(Adapter[i].name, name.c_str(), strlen(name.c_str()));
 
        
        unsigned long long data[32] = {0};
        sscanf(szline+p1+1, "%llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu", 
            data + RX_BYTES,
            data + RX_PACKETS,
            data + RX_ERRS,
            data + RX_DROP,
            data + RX_FIFO,
            data + RX_FRAME,
            data + RX_COMPRESSED,
            data + RX_MULTICAST,
            
            data + TX_BYTES,
            data + TX_PACKETS,
            data + TX_ERRS,
            data + TX_DROP,
            data + TX_FIFO,
            data + TX_COLLS,
            data + TX_CARRIER,
            data + TX_COMPRESSED);
 
        Adapter[i].rx_bytes = data[RX_BYTES];
        Adapter[i].rx_packets = data[RX_PACKETS];
        Adapter[i].rx_errs = data[RX_ERRS];
        Adapter[i].rx_drop = data[RX_DROP];

        Adapter[i].tx_bytes = data[TX_BYTES];
        Adapter[i].tx_packets = data[RX_PACKETS];
        Adapter[i].tx_errs = data[RX_ERRS];
        Adapter[i].tx_drop = data[RX_DROP];
     
        memcpy(ifr_mac_ip.ifr_name, name.c_str(), strlen(name.c_str()));

        i++;    
        nCount++;
        memset(szline, 0, sizeof(szline));
    }
 
    fclose(fp);
    close(s);
    return nCount;
}
 
int main(int argc, char **argv)
{
    if(argc!=2)
    {
        printf("usage: client IP \n");
        exit(0);
    }
 
    //
    int sock_cli = socket(AF_UNIX, SOCK_STREAM, 0);
    if(sock_cli < 0){
        printf("Request socket failed\n");
        exit(1);
    } 

    //define socketaddr_un
    struct sockaddr_un un;
    //memset(&servaddr, 0, sizeof(servaddr));
    //servaddr.sin_family = AF_INET;
    //servaddr.sin_addr.s_addr = inet_addr(argv[1]);
    //servaddr.sin_port = htons(PORT);  
    un.sun_family = AF_UNIX;
    strcpy(un.sun_path,filename);
 
    //if success return 0, else < 0
    if (connect(sock_cli, (struct sockaddr *)&un, sizeof(un)) < 0)
    {
        perror("connect");
        exit(1);
    }
    printf("connect server(interface:%s). success \n",argv[1]);
 
    char sendbuf[BUFFER_SIZE];
    char recvbuf[BUFFER_SIZE];
    // send ready to server
    
    
    char rvbuf[] = "Client : Ready......\n";
    //memset(rvbuf, 'R', sizeof(rvbuf));
    send(sock_cli, rvbuf, strlen(rvbuf), 0);

    bool flag = true;
    struct ifreq buf[MAXINTERFACES]; 
    struct arpreq arp; 
    struct ifconf ifc; 
    int intrface;
    while (1)
    {    
        
        if (flag) {
            recv(sock_cli, recvbuf, sizeof(recvbuf),0); ///receive
            fputs(recvbuf, stdout);
            memset(recvbuf, 0, sizeof(recvbuf));
            flag = false;
        } else {
            struct net netlist[20]={0};
            int j = AdapterCount((struct net*)&netlist);
            for(int i=0; i<j; i++)
            {
                if (strcmp(argv[1], netlist[i].name) == 0) 
                {    
                    int fd;
                    if ((fd = socket (AF_INET, SOCK_DGRAM, 0)) >= 0) 
                    { 
                        ifc.ifc_len = sizeof buf; 
                        ifc.ifc_buf = (caddr_t) buf; 
                        if (!ioctl (fd, SIOCGIFCONF, (char *) &ifc)) 
                        { 
                            intrface = ifc.ifc_len / sizeof (struct ifreq); 
                            while (intrface-- > 0) 
                            { 
                                //printf ("net device %s\n", buf[intrface].ifr_name); 
                                if (strcmp(argv[1], buf[intrface].ifr_name) == 0) {
                                    /*Jugde whether the net card status is promisc*/ 
                                    if (!(ioctl (fd, SIOCGIFFLAGS, (char *) &buf[intrface]))) 
                                    { 
                                    } 
                                                        /*Jugde whether the net card status is up*/ 
                                    if (buf[intrface].ifr_flags & IFF_UP) 
                                    { 
                                        sprintf(netlist[i].state, "%s", "UP");
                                        //puts("the interface status is UP"); 
                                        break;
                                    } 
                                    else 
                                    { 
                                        system("sudo ip link set lo up");
                                        sprintf(netlist[i].state, "%s", "DOWN");
                                        //puts("the interface status is DOWN"); 
                                    } 
                                }
                            }
                        }
                    }
                    close(fd);
                
                    
sprintf(sendbuf, "Interface : %s state : %s rx_bytes : %llu rx_packets : %llu rx_errs : %llu rx_drop : %llu tx_bytes : %llu tx_packets : %llu tx_errs : %llu tx_drop : %llu\n", 
                    netlist[i].name, netlist[i].state,
                    netlist[i].rx_bytes, netlist[i].rx_packets, netlist[i].rx_errs, netlist[i].rx_drop, 
                    netlist[i].tx_bytes, netlist[i].tx_packets, netlist[i].tx_errs, netlist[i].tx_drop);
                    sleep(1);
                    send(sock_cli, sendbuf, strlen(sendbuf),0); ///
                    if(strcmp(sendbuf,"exit\n")==0)
                    {
                        printf("client exited.\n");
                        break;
                    }
                    //sleep(100);
                    //printf("the interface is right\n");
                    //printf("Interface : %s %llu %llu %llu %llu %llu %llu %llu %llu \n", 
                    //netlist[i].name, netlist[i].rx_bytes, netlist[i].rx_packets, netlist[i].rx_errs, netlist[i].rx_drop,
                                    // netlist[i].tx_bytes, netlist[i].tx_packets, netlist[i].tx_errs, netlist[i].tx_drop);
                }
                
                
                //printf("%llu\n", netlist[i].rx_bytes);
                //printf("%llu\n", netlist[i].rx_packets);
                //printf("%llu\n", netlist[i].rx_errs);
                //printf("%llu\n", netlist[i].rx_drop);

                //printf("%llu\n", netlist[i].tx_bytes);
                //printf("%llu\n", netlist[i].tx_packets);
                //printf("%llu\n", netlist[i].tx_errs);
                //printf("%llu\n", netlist[i].tx_drop);
                //printf("\n");
            }        
        }
        memset(sendbuf, 0, sizeof(sendbuf));
        memset(recvbuf, 0, sizeof(recvbuf));
        //if (fgets(sendbuf, sizeof(sendbuf), stdin) != NULL) {
        //    send(sock_cli, sendbuf, strlen(sendbuf),0); 
        //    if(strcmp(sendbuf,"exit\n")==0)
        //    {
        //        printf("client exited.\n");
        //        break;
        //    }
            //printf("client receive:\n");
        //    recv(sock_cli, recvbuf, sizeof(recvbuf),0);
            //fputs(recvbuf, stdout);
         
        //    memset(sendbuf, 0, sizeof(sendbuf));
        //    memset(recvbuf, 0, sizeof(recvbuf));
        //}
    }
 
    close(sock_cli);
    return 0;
}
 
 
 

服务端代码:

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/shm.h>
#include<sys/un.h>
 
#define PORT  8890
#define QUEUE_SIZE   10
#define BUFFER_SIZE 1024

const char *filename="/tmp/sss";

 
void str_echo(int sockfd)
{
    char buffer[BUFFER_SIZE];
    pid_t pid = getpid();
    bool flag = true;
    while(1)
    {
    
        memset(buffer,0,sizeof(buffer));
        int len = recv(sockfd, buffer, sizeof(buffer),0);
        if(strcmp(buffer,"exit\n")==0)
        {
            printf("child process: %d exited.\n",pid);
            break;
        }
        //printf("pid:%d receive:\n",pid);
        fputs(buffer, stdout);
        //printf("\n");
        //
        if (flag) 
        {
            // write Monitor
            char rvbuf[] = "Server : Monitor......\n";
            send(sockfd, rvbuf, strlen(rvbuf), 0);
            flag = false;
        }else {
            //send(sockfd, buffer, len, 0);        
            //sleep(1);
        }
    }
    close(sockfd);
}
 
int main(int argc, char **argv)
{

    int server_sockfd = socket(AF_UNIX,SOCK_STREAM, 0);
    if(server_sockfd < 0){
        printf("Request socket failed!\n");
        exit(1);
    }
 
    //define sockaddr_un
    struct sockaddr_un un;
    //struct sockaddr_in server_sockaddr;
    //server_sockaddr.sin_family = AF_INET;
    //server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    //server_sockaddr.sin_port = htons(PORT);
    un.sun_family = AF_UNIX;
    unlink(filename);
    strcpy(un.sun_path,filename);
    
    
    if(bind(server_sockfd,(struct sockaddr *)&un, sizeof(un))==-1)
    {
        perror("bind");
        exit(1);
    }
    printf("bind success.\n");
 

    //
    if(listen(server_sockfd, QUEUE_SIZE) == -1)
    {
        perror("listen");
        exit(1);
    }
    printf("listen success.\n");
 
    for(;;)
    {
        struct sockaddr_un client_addr;
        socklen_t length = sizeof(client_addr);
        //
        int conn = accept(server_sockfd, (struct sockaddr*)&client_addr,&length);
        if(conn<0)
        {
            perror("connect");
            exit(1);
        }
        //printf("new client accepted. \n");
 
        pid_t childid;
        if(childid=fork()==0)
        {
            printf("child process: %d created.\n", getpid());
            close(server_sockfd);
            str_echo(conn);
            exit(0);
        }
    }
 
    printf("closed.\n");
    close(server_sockfd);
    return 0;
}
 
 

 

运行结果如下:

unix socket实现网卡接口多线程监控 rx_packets, tx_packets, rx_errs, tx_errs等数据