【问题标题】:Two pcap_compile() on one device at same time?一台设备上同时有两个 pcap_compile()?
【发布时间】:2020-06-10 16:52:31
【问题描述】:

我有两个线程,每个线程同时从同一设备捕获数据包,但是当第二个线程到达pcap_compile() 函数时程序崩溃。此外,每个线程都有自己的变量,不使用全局变量。他们似乎获得了相同的设备句柄,因此程序崩溃了。为什么我需要两个线程?因为我想通过指定的pcap 过滤器将发送和接收的数据包分开。那么我该如何解决呢?还是使用一个线程并使用tcp标头中的地址手动对发送和接收的数据包进行排序更好?

【问题讨论】:

    标签: c++ winpcap


    【解决方案1】:

    pcap_compile 不是线程安全的。您必须用临界区/互斥锁包围单独线程可能遇到的所有调用,以防止由于编译表达式的解析器中的非线程安全状态而导致错误(对于血淋淋的细节,它使用 YACC 为解析表达式和为此生成的代码明显不是线程安全的)。

    您需要为您计划用于捕获的每个线程显式打开一次设备,如果您在多个线程中重复使用相同的设备句柄,那么它根本不会满足您的要求。您应该在计划使用它的线程中打开 pcap 句柄,因此计划进行捕获的每个线程都应该使用自己的pcap_open

    要使用临界区保护对pcap_compile 的调用,您可以创建一个简单的包装器(Windows 临界区的 C++ 包装器):

    class lock_interface {
    public:
        virtual void lock() = 0;
        virtual void unlock() = 0;
    };
    
    class cs : public lock_interface {
        CRITICAL_SECTION crit;
    public:
        cs() { InitializeCriticalSection(&crit); }
        ~cs() { DeleteCriticalSection(&crit); }
        virtual void lock() {
            EnterCriticalSection(&crit);
        }
        virtual void unlock() {
            LeaveCriticalSection(&crit);
        }
    private:
        cs(const locker &);
        cs &operator=(const cs &);
    };
    
    class locker {
        lock_interface &m_ref;
    public:
        locker(lock_interface &ref) : m_ref(ref) { m_ref.lock(); }
        ~locker() { m_ref.unlock(); }
    private:
        locker(const locker &);
        locker &operator=(const locker &);
    };
    
    static cs section;
    
    int
    wrapped_pcap_compile(pcap_t *p, struct bpf_program *fp, const char *str, int optimize, bpf_u_int32 netmask)
    {
        locker locked(section);
        pcap_compile(p, fp, str, optimize, netmask);
    }
    

    【讨论】:

      【解决方案2】:

      如果你使用的是 C++11,你可以有类似的东西:

      int thread_safe_pcap_compile_nopcap(int snap_len, int link_type,
                                          struct bpf_program *fp, char const *str,
                                          int optimize, bpf_u_int32 netmask) {
          static std::mutex mtx;
          std::lock_guard<std::mutex> lock(mtx);
          return pcap_compile_nopcap(snap_len, link_type, fp, str, optimize, netmask);
      }
      

      pcap_compile 函数类似。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-16
        • 2021-09-18
        • 1970-01-01
        • 2018-06-23
        • 2013-04-12
        • 2020-06-15
        相关资源
        最近更新 更多