Три причины:
1) Правильнее настроить намного проще.
2) Он переносим даже на Windows, который использует довольно похожий, но другой API для сокетов.
3) Это НАМНОГО быстрее.
1 и 2, ИМО, не нужно много объяснений. Я углублюсь в 3.
Чтобы понять, почему libpcap (как правило) быстрее, нам нужно понять узкие места в API сокетов.
Два самых больших узких места, которых libpcap стремится избежать, это системные вызовы и копии.
Как это происходит, зависит от платформы c.
Я расскажу историю для Linux.
Linux, поскольку 2.0 IIR C, реализует то, что называется семейством сокетов AF_PACKET, а затем и PACKET_MMAP. Я не совсем помню преимущества первого, но последнее крайне важно, чтобы избежать как копирования из ядра в пользовательское пространство (есть еще несколько копий на стороне ядра), так и системных вызовов.
В PACKET_MMAP вы выделяете большой кольцевой буфер в пользовательском пространстве, а затем связать его с сокетом AF_PACKET. Этот кольцевой буфер будет содержать немного метаданных (наиболее важно, маркер, который говорит, готов ли регион для обработки пользователем) и содержимое пакета.
Когда пакет поступает в соответствующий интерфейс (обычно тот, который вы связываете) ваш сокет в), ядро делает копию в кольцевом буфере и помечает местоположение как готовое для пространства пользователя *. Если приложение ожидает в сокете, оно получает уведомление *.
Итак, почему это лучше, чем необработанные сокеты? Потому что после настройки сокета вы можете делать с несколькими системными вызовами или вообще без них, в зависимости от того, хотите ли вы заняться опросом самого буфера или подождать с poll
, пока несколько пакетов не будут готовы, и потому что вам не нужна копия из внутренний RX-буфер сокета для ваших пользовательских буферов, поскольку он используется совместно с вами.
libpcap сделает все это за вас. И делает это на Ma c, * BSD и практически на любой платформе, которая предоставляет вам более быстрые методы захвата.
* Это немного сложнее в версии 3, где вместо этого гранулярность находится в «блоках» пакетов.