kaitoy / pcap4j

A Java library for capturing, crafting, and sending packets.

Home Page:https://www.pcap4j.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How to solve the problem of packet loss during packet capture?

ZhizhangMO opened this issue · comments

When I test the sample of Loop, if the network speed exceeds a certain rate, packet loss will occur.
The number of packets captured by Loop is only 1/3 of wireshark. How can I solve this problem. I have tested in a environment that the download rate is 2Mb/s, 4Mb/s or 8Mb/s, and the packet loss rate is always close to 1/3.

Here is my cord:

import com.sun.jna.Platform;
import org.pcap4j.core.BpfProgram.BpfCompileMode;
import org.pcap4j.core.*;
import org.pcap4j.core.PcapNetworkInterface.PromiscuousMode;
import org.pcap4j.packet.Packet;
import org.pcap4j.util.NifSelector;

import java.io.IOException;

@SuppressWarnings("javadoc")
public class Loop {

    private static final String COUNT_KEY = Loop.class.getName() + ".count";
    private static final int COUNT = Integer.getInteger(COUNT_KEY, -1);

    private static final String READ_TIMEOUT_KEY = Loop.class.getName() + ".readTimeout";
    private static final int READ_TIMEOUT = Integer.getInteger(READ_TIMEOUT_KEY, 10); // [ms]

    private static final String SNAPLEN_KEY = Loop.class.getName() + ".snaplen";
    private static final int SNAPLEN = Integer.getInteger(SNAPLEN_KEY, 65536); // [bytes]

    //The number of packets captured
    private static int x;

    private Loop() {}

    public static void main(String[] args) throws PcapNativeException, NotOpenException {
        String filter = args.length != 0 ? args[0] : "";

        System.out.println(COUNT_KEY + ": " + COUNT);
        System.out.println(READ_TIMEOUT_KEY + ": " + READ_TIMEOUT);
        System.out.println(SNAPLEN_KEY + ": " + SNAPLEN);
        System.out.println("\n");

        PcapNetworkInterface nif;
        try {
            nif = new NifSelector().selectNetworkInterface();
        } catch (IOException e) {
            e.printStackTrace();
            return;
        }

        if (nif == null) {
            return;
        }

        System.out.println(nif.getName() + "(" + nif.getDescription() + ")");

        final PcapHandle handle = nif.openLive(SNAPLEN, PromiscuousMode.PROMISCUOUS, READ_TIMEOUT);

        if (filter.length() != 0) {
            handle.setFilter(filter, BpfCompileMode.OPTIMIZE);
        }

        Object lock = new Object();

        PacketListener listener =
                new PacketListener() {
                    @Override
                    public void gotPacket(Packet packet) {
//                        System.out.println(handle.getTimestamp());
//                        System.out.println(packet);
                        synchronized (lock) {
                            System.out.println("====>" + x++);
                        }
                    }
                };

        try {
            handle.loop(COUNT, listener);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        PcapStat ps = handle.getStats();
        System.out.println("ps_recv: " + ps.getNumPacketsReceived());
        System.out.println("ps_drop: " + ps.getNumPacketsDropped());
        System.out.println("ps_ifdrop: " + ps.getNumPacketsDroppedByIf());
        if (Platform.isWindows()) {
            System.out.println("bs_capt: " + ps.getNumPacketsCaptured());
        }

        handle.close();
    }
}

try this.
ExecutorService pool = Executors.newCachedThreadPool();
handle.loop(-1, listener, pool);
pool.shutdown();

how to solve out order?