先利用nethogs将进程的收发速率写进log文件,再对文件进行读取
1 #define SHELL "/bin/bash"
2 #include<string.h>
3 #include<stdlib.h>
4 #include<sys/time.h>
5 #include<stdio.h>
6 #include<unistd.h>
7 #include<iostream>
8 #include <sys/types.h>
9 #include <sys/wait.h>
10
11 static pid_t *childpid=NULL;/*ptr to array allocated at run-time*/
12 static int maxfd; /*from our open_max(), {Prox openmax}*/
13 float readdata(int pid);
//这里由于Nethogs打开之后需要关闭 而popen函数并不对于子进程进行操作,只是等命令进行完之后再进一步继续,因此需要重写popen函数,在pclose时对子进程kill
20 FILE *popen2(const char *cmdstring, const char *type)
21 {
22 int i, pfd[2];
23 pid_t pid;
24 FILE *fp;
25
26 /*only allow "r" or "w"*/
27 if(type[0] != 'r' && type[0]!='w' || type[1] != 0) {
28 errno=EINVAL;
29 return (NULL);
30 }
31 if(childpid == NULL) {/*first time throngh, allocate zeroed out array for child pids*/
32 maxfd = sysconf(_SC_OPEN_MAX);
33 if((childpid =(pid_t*) calloc(maxfd, sizeof(pid_t))) == NULL){
34 return(NULL);
35 }
36 }
37 if(pipe(pfd) < 0){
38 return(NULL);
39 } //errno set by pipe()
40 if((pid = fork()) < 0){
41 return(NULL); //error set by fork()
42 }
43 else if(pid==0) { /*child*/
44 if(*type == 'r') {
45 close(pfd[0]);
46 if(pfd[1] != STDOUT_FILENO) {
47 dup2(pfd[1], STDOUT_FILENO);
48 close(pfd[1]);
49 }
50 } else {
51 close(pfd[1]);
52 if(pfd[0] != STDIN_FILENO) {
53 dup2(pfd[0], STDIN_FILENO);
54 close(pfd[0]);
55 }
56 }
57 /*close all descriptiors in childpid*/
58 for(i = 0; i < maxfd; i++)
59 if(childpid[i] > 0)
60 close(i);
61 execl(SHELL, "bash", "-c", cmdstring, (char *)0);
62 _exit(127);
63 }
64
65 /*parent*/
66 if(*type == 'r') {
67 close(pfd[1]);
68 if((fp = fdopen(pfd[0], type)) == NULL)
69 return (NULL);
70 }else {
71 close(pfd[0]);
72 if((fp = fdopen(pfd[1], type)) == NULL)
73 return (NULL);
74 }
75 childpid[fileno(fp)] = pid; /*remember child pid for this fd*/
76 return(fp);
77 }
78
79
80 int pclose2(FILE *fp)
81 {
82 int fd, stat;
83 pid_t pid;
84 printf("hello>>>>>>>>>>>>>\n");
85 if(childpid == NULL) /*popen() has never benn called*/
86 return (-1);
87
88 fd = fileno(fp);
89 if((pid = childpid[fd]) == 0)
90 return (-1); //fp wasn't opened by popen()
91
92 childpid[fd] = 0;
93 if(fclose(fp) == EOF)
94 return (-1);
95 if( kill(pid, SIGKILL) != 0) {
96 printf("kill failed\n");
97 perror("kill");
98 }
99 else {
100 printf("%d killed\n", pid);
101 }
110 int get_pid(const char* process_name, const char* user = nullptr)//根据进程名获得pid
111 {
112 if(user == nullptr){
113 user = getlogin(); //若没有输入用户名,则认为用户名为当前登录名
114 }
115
116 char cmd[512];
117 if (user){
118 sprintf(cmd, "pgrep %s -u %s", process_name, user); //cmd="pgrep process_name -u us er" 返回进程ID
119 }
120
121 FILE *pstr = popen(cmd,"r");
122
123 if(pstr == nullptr){
124 return 0;
125 }
126
127 char buff[512];
128 ::memset(buff, 0, sizeof(buff));
129 if(NULL == fgets(buff, 512, pstr)){//指定的流 stream 读取一行,并把它存储
130 return 0;
131 }
132
133 return atoi(buff); //返回整数
134 }
138 //输出发送速率到log.txt
139 float get_send(int pid)
140 {
141 char cmd[512]="sudo nethogs -a -t>log.txt"; //这里一定要是trace模式,不然写进去是乱码,不懂为什么
142 //printf("cmd=%s\n",cmd);
143 FILE *pstr = popen2(cmd,"r");
144 if(nullptr == pstr){
145 printf("打开nethogs命令失败!\n");
146 return -1;
147 }
148 usleep(500000); //这里需要注意,写进文件之后需要一定时间才可以进行操作。
149 pclose2(pstr);
150 usleep(500000);
151 float read_rate;
152 read_rate = readdata(pid);
153
154 return read_rate;
155 }
157 float readdata(int pid) //从log.txt中读取发送速率
158 {
159 //创建文件流,文件指针名=fopen(文件名,使用文件方式)打开失败则返回NULL;
160 FILE *fp=fopen("./log.txt","r");
161 //检测文件是否打开成功;
162 if(!fp){
163 printf("打开失败!\n");
164 return -1; //返回异常
165 }
166 char name[10];
167 char third[10];
168 char readpid[5];
169 float sendrate,recerata; //用来储存收发速度
170 fscanf(fp, "%*c%*[^\n]%*c");
171 fscanf(fp, "%*c%*[^\n]%*c");
172 fscanf(fp, "%*c%*[^\n]%*c");
173 fscanf(fp, "%*c%*[^\n]%*c");
174 fscanf(fp, "%*c%*[^\n]%*c");
175 fscanf(fp, "%*c%*[^\n]%*c");
176 fscanf(fp, "%*c%*[^\n]%*c");
177 fscanf(fp, "%*c%*[^\n]%*c");
178 fscanf(fp, "%*c%*[^\n]%*c");
181 while(fscanf(fp,"./%[^'/']/%[^'/']/%s %f %f\n",&name,&readpid,&third,&sendrate,&recerata )>0){
182 printf("%s %s %s %lf %lf",&name,&readpid,&third,sendrate,recerata);
183 if(pid==atoi(readpid)){
184 printf("%s %s %s %lf %lf",&name,&readpid,&third,sendrate,recerata);
185 printf("成功读取发送速率!\n");
186 fclose(fp);
187 return sendrate;
188 }
189 }
190 printf("read sendrate fail!\n");
191 fclose(fp);
192 return 0;
193 }
195 int main(int argc, char *argv[])
196 {
197 while(1){
198
199 if(argc < 2){
200 printf("Usage:test <process_name> [user]\n");//调用格式: ./getinfo > 进程名
201 return 1;
202 }
203
204 unsigned int pid=0;
205
206 if(argc > 2){
207 pid = get_pid(argv[1],argv[2]);
208 }
209 else{
210 pid = get_pid(argv[1]);
211 }
212 printf("pid=%d\n",pid);
213 printf("send=%lf\n",get_send(pid));
214 usleep(2000000);
215 }
216
217 return 0;
218 }
重写的popen函数:https://blog.csdn.net/w18mc0431/article/details/52132447
单步调试正确,但是运行错误:https://blog.csdn.net/duguduchong/article/details/5998152?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&dist_request_id=&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.control