monitor模式和AP模式下,一段时间都会停止收数
原因:
1、Log_to_file退出并显示错误:“recv:no buffer space available”。由于Log_to_file无法调用了所以停止计数
2、 System call slows down the process which can fill the memory(由于内存原因,系统停止进程)
3、当socket 进行TCP 连接的时候(也就是调用connect 时),一旦网络不通,或者是ip 地址无效,就可能使整个线程阻塞。
解决方法:
1、增加了进程log_to_file的调度优先级
增加了进程log_to_file的调度优先级,让其不间断地连续运行
sudo renice -n -20 -p pid(log_to_file对应的pid)
sudo renice -n -20 -p pid /……/log_to_file tmp.dat
尝试其它指令:
Linux系统进程的优先级取值:-20 到 19,数越大优先级越低。
命令1:sudo nice -20 /……/log_to_file tmp.dat,还是会出收数停止的情况
命令2:sudo nice --20 /……/log_to_file tmp.dat,还是会出现停止收数的情况
注:查看log_to_file进程的PID方法:
1、让发端和收端都正常运行,收端运行log_to_file不停收数
2、在收端打开一个新的终端,输入下面的指令
pgrep -l XXX,这里第三个参数修改为log_to_file
这时终端中会显示出进程log_to_file的进程号为2357
重新收数,再次查看log_to_file的进程号,此时变为2755
重启主从机运行log_to_file后查看进程号显示为2396
3、运行前log_to_file没有对应的进程号,运行后才有进程号,只能运行后再修改优先级
查看内存及cpu使用情况的命令:top
同样在新的终端下top,只要一直在收数就可以看到 log_to_file对应的一行信息,当收数停止后,这一行信息也会消失
设置优先级我这里不奏效
2、内存
内存的使用情况怎么去查看?
在新终端窗口直接输入 free -m 命令,可使用的mem大概有60M,停止收数时还有大量的可用内存空间
内存和no buffer区别?
3、修改发包长度
从默认值100修改为10,不起作用
3、修改log_to_file.c文件,重编译运行
1、buf[4096]修改为buf[8192],还是出现停止收数的情况
2、MAX_PAYLOSAD修改为4096
3、log_to_file.c中的while(1)循环收数
在while(1)外加了一句printf,停止收数的时候,没有打印任何信息,说明没有退出while(1)循环
停止收数后,隔一段时间后终端会继续打印,count会接着之前的数继续往后打印,不会中断,并且记录数据的文件大小会继续增加(停止的时候,文件大小才自动增加)
while (1)
{
/* Receive from socket with infinite timeout */
ret = recv(sock_fd, buf, sizeof(buf), 0);
if (ret == -1)
exit_program_err(-1, "recv");
/* Pull out the message portion and print some stats */
cmsg = NLMSG_DATA(buf);
if (count % SLOW_MSG_CNT == 0)
printf("received %d bytes: id: %d val: %d seq: %d clen: %d\n", cmsg->len, cmsg->id.idx, cmsg->id.val, cmsg->seq, cmsg->len);
/* Log the data to file */
l = (unsigned short) cmsg->len;
l2 = htons(l);
fwrite(&l2, 1, sizeof(unsigned short), out);
ret = fwrite(cmsg->data, 1, l, out);
if (count % 100 == 0)
printf("wrote %d bytes [msgcnt=%u]\n", ret, count);
++count;
if (ret != l)
exit_program_err(1, "fwrite");
}
①在exit_program_err()和exit_program()子函数 中加入了fprint语句,永远都不会打印出来,程序到底停在那里?
② fwrite(&l2, 1, sizeof(unsigned short), out);此句含义?
ret = fwrite(cmsg->data, 1, l, out);向文件写入数据
补充:修改log_to_file.c文件后可以直接运行log_to_file生成带年月日的文件,没必要每次发指令都写文件名
4、在log_to_file.c中修改log_to_file的进程优先级
5、通过PS指令发现进程停止
ps -s -p 进程pid查看log_to_file的状态,发现运行时为s+,停止计数是仍为s+(出现过S<+)
重新唤醒进程
6、修改socket
recv函数:如果recv函数在等待协议接收数据时网络断开了,那么调用recv的进程会接收到一个SIGPIPE信号,进程对该信号的默认处理是进程终止。(停止计数后出现断网的解释https://blog.csdn.net/a4150902/article/details/7399578)
设置为非阻塞:https://blog.csdn.net/zwg739424406/article/details/80006234(阻塞和非阻塞的理解)
先理一下阻塞和非阻塞的概念:
- 阻塞就是让当前调用线程一直处于停止等待当中,挂起的状态,线程函数会被卡住。
- 非阻塞则是不管运行结果如何,都会继续往下执行(往往都要处理很多返回结果),线程函数里一般都是一个循环,不停的轮询。
再理一下发送接收函数:
- send/sendto函数,只是把应用层的数据拷贝到内核发送缓冲区,并不保证数据一定会被发送到对端,真正执行发送及什么时候发送是由系统(协议栈)决定的,所以send/sendto函数返回成功,只能说明拷贝成功了,如果在还未发送之前网络断开,则发送失败。
- recv/recvform函数,,将内核接收缓冲区的数据拷贝到应用层的buffer中,真正执行接收数据也是由系统层决定的。
套接字默认是阻塞状态,因此发送及接收也是阻塞状态,所以调用不会立即返回,而是进入睡眠等待操作完成。
1.在阻塞模式下,recv/recvfrom会一直阻塞到接收缓冲区里有一个字节或一个完整的UDP数据报为止,然后再返回
- recv的原型:int recv(SOCKET sd, char *buffer, int len, int
flag),注意到系统并不会等待buffer被填满了再返回,而是一旦有数据被接收到,就立刻返回,因此不要期望实际收到的数据长度就等于len。
2.在非阻塞模式下,recv/recvfrom会立即返回
- 如果接收缓冲区,有至少一个字节或UDP数据报,则会返回接收到的数据大小,如果没有,则返回错误EWOULDBLOCK
SOCKET s;
unsigned long ul = 1;
int ret;
s = socket(AF_INET, SOCK_STREAM, 0);
ret = ioctlsocket(s, FIONRIO, (unsigned long)&ul);
if(SOCKET_ERROR==ret)
{
//未能将套接字设置为非阻塞模式
}
①FIONBIO编译不过:加上头文件#include <asm/ioctls.h>
②nRet = ioctlsocket(s, FIONBIO, (unsigned long*)&ul); 设置套接字非阻塞模式,函数ioctlsocket不存在?
修改方法:WSAAsyncselect()和WSAEventselect()函数
③
参数区别:https://blog.csdn.net/bigjacky/article/details/51622185
7、修改recv函数
ssize_t recvfrom(int sockfd,void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen)
windows版本:
int recvfrom(IN SOCKET s, OUT char FAR * buf, IN int len, IN int flags, OUT struct sockaddr FAR * from,IN OUT int FAR * fromlen)
着重强调参数:
sockfd:接收端套接字描述
buf:用于接收数据的应用缓冲区地址
len:指名缓冲区大小
flags:通常为0
src_addr:数据来源端的地址
addrlen:src_addr地址的长度
注意后两个参数是输出参数,其中addrlen既是输入又是输出参数,即值-结果参数,需要在调用时,指明src_addr的长度。另外,如果不关心数据发送端的地址,可以将后两者均设置为NULL
GitHub上有人解决了,真的不知道你是咋解决的....
关于缓存超过的解决方法:https://github.com/dhalperi/linux-80211n-csitool-supplementary/issues?q=
终止进程
sudo kill 3545(进程PID)