【问题标题】:Why a simple program does not start right away为什么一个简单的程序不能立即启动
【发布时间】:2019-03-07 03:22:47
【问题描述】:

由于不知道与这个问题相关的关键词,所以无法具体询问。

问题是如果在以下源中运行程序,程序不会立即运行。

#include <iostream>

#include <pcap/pcap.h>

int main() {
  bool stop = false;
  pcap_t *pcp = nullptr;
  pcap_pkthdr *pkthdr = nullptr;
  const u_char *packet = nullptr;
  char errbuf[PCAP_ERRBUF_SIZE];
  int res = 0;

  //It works normally. "here" printed.
  std::cout << "here"
  //----------- I think pcap_open_live() block the program --------------
  pcp = pcap_open_live("enp0s3", BUFSIZ, 0, -1, errbuf);
  //if run following, the program print "captured!" phrase.
  //std::cout << "any string\n";
  if (pcp == nullptr) {
    return 0;
  }
  //if run following, the program print "captured!" phrase.
  //std::cout << "any string\n";
  while (!stop) {
    while (res == 0) {
      res = pcap_next_ex(pcp, &pkthdr, &packet);
    }
    if (res < 0) {
      stop = true;
    } else {
      std::cout << "captured!\n";
    }
  }

  return 0;
}

程序在以下两个条件下执行。

  • 输入任意键
  • 像评论一样打印标准输出

为什么会发生这种情况,程序如何立即运行?

【问题讨论】:

  • 你不能调试它以找出它阻塞的地方吗?
  • 您使用什么标准来确定程序是否执行? (即,您希望看到的 stdout 上是否有一些特定的输出,或者一些网络行为,或者???)
  • @JeremyFriesner "captured!\n" 我想打印这个短语
  • @Sanjeev 我认为pcap_next_ex(pcp, &amp;pkthdr, &amp;packet) 函数第一次被阻塞了..
  • @김현우 将在 pcap_open 调用中定义超时值,您必须查看它。还将 print("captured") 语句放在 else 块中。如果 pcap_next_ex 返回 0 则超时,在这种情况下您不应该打印捕获的内容。

标签: c++ linux pthreads flush


【解决方案1】:

我认为您的问题是您在调用时为 to_ms 设置了一个负值,即缓冲区超时

pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, char *errbuf)

正如here 中所说,pcap_open_live() 中的第四个参数

指定数据包缓冲区超时,作为非负值,在 毫秒

如果您阅读主要的pcap page,它会声明

数据包缓冲超时

如果在捕获时,数据包被传递为 一旦它们到达,捕获数据包的应用程序将 在每个数据包到达时唤醒它,并且可能必须制作一个或 对操作系统的更多调用以获取每个数据包。如果相反, 数据包不是一到就送达,而是送达 在短暂的延迟(称为“数据包缓冲区超时”)之后,多个 数据包可以在数据包被传递之前被累积,因此一个 单个唤醒将对多个数据包进行,并且每组 对操作系统的调用将提供多个数据包, 而不是单个数据包。这减少了每个数据包的 CPU 开销 如果数据包以高速率到达,则增加 每秒可以捕获的数据包。数据包缓冲区超时为 必需的,这样应用程序就不会等待操作系统的 捕获缓冲区在数据包被传递之前填满;如果数据包是 到达缓慢,等待可能需要任意长的时间 时间。

在本段的末尾指出:

负值无效;将超时设置为的结果 负值是不可预测的。

因此我建议您尝试将其设置为 0 或正值,以查看行为是否符合预期。

【讨论】:

    【解决方案2】:

    如果在 Nat 环境中使用 ssh 运行程序,“捕获!”输出发生在实际传输的数据包中。问题不是阻塞,而是没有实际的传输数据包。感谢您的关注。

    【讨论】:

      猜你喜欢
      • 2015-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多