【问题标题】:Socket read with pcap使用 pcap 读取套接字
【发布时间】:2012-09-16 11:50:19
【问题描述】:

我有一个绑定到 NIC 的套接字,我用它来捕获 pcap_loop 中的数据包。

我有一个单独的进程正在运行,最终在同一设备上执行“读取”,但只有在准备好读取 unix 本地管道之后。是否正确地说第二个进程的设备上的 read() 将读取准备好的所有内容,而不仅仅是一个数据包,即使我的另一个进程设置为使用 pcap_loop 一次读取一个数据包?

【问题讨论】:

    标签: sockets freebsd pcap


    【解决方案1】:

    我有一个绑定到 NIC 的套接字,我用它来捕获 pcap_loop 中的数据包。

    你说“socket”,所以我猜这是 Linux(它也可能是 IRIX,但可能性要小得多,两种情况下的答案都是一样的;其他操作系统不使用套接字libpcap,这些操作系统上的本机捕获机制使用套接字以外的机制)。

    我有一个单独的进程正在运行,最终在同一设备上执行“读取”,但只有在准备好读取 unix 本地管道之后。是否正确地说第二个进程的设备上的 read() 将读取所有准备好的内容,而不仅仅是一次一个数据包,

    没有。 PF_PACKET 套接字一次从read() 返回一个数据包。

    顺便说一句,不能保证从套接字读取并同时在 libpcap 中处理同一个套接字会起作用。 Libpcap 可能正在使用内存映射机制来获取数据包;除非你在其他地方看到过关于内存映射机制如何与read()s 一起工作的文档,或者已经阅读了足够多的 Linux 内核代码来弄清楚它是如何工作的,否则你可能不想假设它会按照你的方式工作想要。

    但是,如果这是 FreeBSD,正如标签所建议(但未说明),那么 libpcap 使用的是 BPF 设备,*不是*插座。 read() 会给你一个完整的数据包缓冲区,而 libpcap 完成的read()s 会给 libpcap 一个完整的数据包缓冲区,即使它碰巧每个数据包调用一次你的回调。 read() 与内存映射访问的相同问题可能会发生,但 FreeBSD 更高版本中的内存映射 BPF 默认情况下不被 libpcap 使用。

    【讨论】:

    • 感谢您的回复。确实,我的命名可能有误,而且在 FreeBSD 中也是如此。我只是假设 pcap_loop(...mymethod...) 每个数据包调用一次 mymethod ,因为当我在该方法中解析数据包时似乎就是这种情况。由于程序的流程,这让我感到困惑,似乎一次读取一个数据包的进程 B 可能落后于为每个数据包获取完整缓冲区的进程 A。
    • pcap_loop() 确实每个数据包调用一次回调。但是,这并不意味着它会使用单独的read() 读取每个数据包。它读取整个缓冲区的数据包,然后遍历缓冲区中的数据包并为每个数据包调用回调。然后它执行另一个 read() 并继续该过程(只要 cnt 参数为 -1)。
    猜你喜欢
    • 2014-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-27
    • 2012-04-22
    • 2017-10-19
    • 2012-10-15
    相关资源
    最近更新 更多