首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在非NONBLOCKING模式下创建多个TCP连接时内核日志中的net_ratelimit消息

在非NONBLOCKING模式下创建多个TCP连接时内核日志中的net_ratelimit消息
EN

Stack Overflow用户
提问于 2016-08-08 10:10:44
回答 1查看 1.5K关注 0票数 1

我有一个C程序,它试图轮询网络中的设备,如果设备可用,它会尝试从它们读取值。但是,当没有设备时,应用程序的运行会在内核日志中创建以下消息。此外,日志中没有其他警告/警报消息,只有下面的消息。(即使在禁用了使用net.core.message_cost=0的比率消除之后)

代码语言:javascript
复制
net_ratelimit: xx callbacks supressed

同时,另一个通过网络广播消息的应用程序在发送系统调用中开始失败,返回EINVAL。一旦我停止轮询TCP客户机,UDP Broadcast应用程序就能正常运行。

我运行它的系统是一个基于RAMFS的系统,运行3.14系列内核RT_PREEMPT 修补程序应用。我编写了一个示例应用程序,当我在后台启动5个进程时,它模拟了与我的原始应用程序相同的行为。(请注意,触发它的进程超过4个)。下面是示例客户端代码。

代码语言:javascript
复制
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <netinet/in.h>

#include <unistd.h>
#include <errno.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define CHK_NULL(x) if ((x)==NULL) exit (1)
#define CHK_ERR(err,s) if ((err)==-1) { perror(s); exit(1); }
#define CHK_SSL(err) if ((err)==-1) { ERR_print_errors_fp(stderr); exit(2); }

int sfd;

void openProtocol(const char *hostname) {
     int sfd = socket(PF_INET, SOCK_STREAM, 0);
     CHK_ERR(sfd, "socket");

     struct sockaddr_in address;
     memset(&address, 0, sizeof(address));
     address.sin_family = PF_INET;
     address.sin_addr.s_addr = inet_addr(hostname);
     address.sin_port = htons(502);

     int opt = 1;
     int result = ioctl(sfd, FIONBIO, &opt);
     if (result == -1) {
      close(sfd);
      CHK_ERR(result, "ioctl");
     }

     result = connect(sfd, (struct sockaddr*)&address, sizeof(address));
     if (result == -1 && errno != EINPROGRESS) {
      close(sfd);
      CHK_ERR(result, "connect");
     }

     fd_set fdlist;
     FD_ZERO(&fdlist);
     struct timeval tm;
     tm.tv_sec = 1;
     tm.tv_usec = 0;

     result = select(sfd + 1, NULL, &fdlist, NULL, &tm);
     if (result == 0) {
      printf ("TCP/IP connection error!\n");
      close(sfd);
     }

     if (result == -1) {
      close(sfd);
      CHK_ERR(result, "select");
     }
}

int main(int argc, char *argv[])
{
     char *base_addr = "192.168.1.";
     unsigned short startAddr = 21;

     if ( argc < 3) {
      fprintf (stderr, "Please provide number of IP and wait period\n");
      exit(EXIT_FAILURE);
     }

     unsigned int no_of_ip;
     if (sscanf (argv[1], "%u", (unsigned int*)&no_of_ip) != 1 ) {
      fprintf (stderr, "Scan of number of device failed\n");
      exit(EXIT_FAILURE);
     }

     unsigned int wait_period;
     if (sscanf (argv[2], "%u", (unsigned int*)&wait_period) != 1) {
      fprintf (stderr, "Scan of wait period failed\n");
      exit(EXIT_FAILURE);
     }

     char full_addr[100];
     char last_part[10];
     while (1) {
      for (int i = startAddr; i < (startAddr + no_of_ip); i++) {
           memset(&full_addr[0], 0, sizeof(full_addr));
           memset(&last_part[0], 0, sizeof(last_part));
           strncat (full_addr, base_addr, sizeof(full_addr));
           snprintf (last_part, sizeof(last_part), "%u", i);
           strncat (full_addr, last_part, sizeof(full_addr));

           openProtocol(full_addr);
           usleep(wait_period * 1000);
      }   
     }

     return 0;
}

应用程序将输入作为设备数量和等待时间。我通过一个shell脚本运行上述应用程序的5个实例,其中128 为设备号5为等待时间(5 ms)。

现在是我的问题。

  1. 为什么我在运行这个应用程序时获得(5 实例)的net_ratelimit消息。我试图通过将net_ratelimit设置为0来禁用net_ratelimit,但是除了net_ratelimit消息之外,在内核日志中找不到任何东西。
  2. 为什么一个无关的应用程序(UDP broadcast客户端)在试图发送广播时得到EINVAL。而且,只有当我的轮询应用程序运行时,才会发生这种情况。终止轮询应用程序广播客户端返回正常。

PS:我无法得到更好的标题线,如果有更好的标题线,请建议/编辑;-)。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-04-25 04:18:06

在将内核升级到4.1系列之后,我可以看到消息的原因。实际的根本原因是以下消息

代码语言:javascript
复制
neighbour: arp_cache: neighbour table overflow

然后,我注意到我正在将条目添加到ARP缓存中,这超过了1024,这是默认限制。在解决这个问题后,回调抑制消息的问题停止了。我想这是3.14系列中的一个错误,它没有提供call back supressed消息的实际原因。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38826490

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档