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 1024const 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;
}
运行结果如下: