# 使用 Java 捕获网络数据包

> 原文： [https://javatutorial.net/capture-network-packages-java](https://javatutorial.net/capture-network-packages-java)

该示例演示了如何使用 pcap 和 Java 捕获网络数据包。

要运行示例，您将需要为操作系统安装 libpcap 。 对于 Windows，下载并安装 [WinPcap](https://www.winpcap.org/install/) 。

Ubuntu 用户可以运行以下命令来安装 libpcap：

```java
sudo apt-get install libpcap-dev
```

我们将使用 [jNetPcap](https://sourceforge.net/projects/jnetpcap/) 作为 Java 包装器。 以下示例要求版本 1.4

## 列出网络设备

```java
import java.util.ArrayList;
import java.util.List;

import org.jnetpcap.Pcap;
import org.jnetpcap.PcapIf;

public class NetworkInterfaces {

	public static void main(String[] args) {
		List<PcapIf> alldevs = new ArrayList<PcapIf>(); // Will be filled with NICs
		StringBuilder errbuf = new StringBuilder(); // For any error msgs

		int r = Pcap.findAllDevs(alldevs, errbuf);
		if (r == Pcap.NOT_OK || alldevs.isEmpty()) {
			System.err.printf("Can't read list of devices, error is %s",
					errbuf.toString());
			return;
		}

		System.out.println("Network devices found:");

		int i = 0;
		for (PcapIf device : alldevs) {
			String description = (device.getDescription() != null) ? device
					.getDescription() : "No description available";
			System.out.printf("#%d: %s [%s]\n", i++, device.getName(),
					description);
		}
	}

}

```

## 捕捉数据包

以下完整示例捕获了前 10 个数据包：

```java
import java.util.ArrayList;
import java.util.List;

import org.jnetpcap.Pcap;
import org.jnetpcap.PcapIf;
import org.jnetpcap.packet.PcapPacket;
import org.jnetpcap.packet.PcapPacketHandler;
import org.jnetpcap.protocol.network.Ip4;

public class PackageCapture {

	public static void main(String[] args) {
		List<PcapIf> alldevs = new ArrayList<PcapIf>(); // Will be filled with NICs
		StringBuilder errbuf = new StringBuilder(); // For any error msgs

		int r = Pcap.findAllDevs(alldevs, errbuf);
		if (r != Pcap.OK || alldevs.isEmpty()) {
			System.err.printf("Can't read list of devices, error is %s",
					errbuf.toString());
			return;
		}

		System.out.println("Network devices found:");

		int i = 0;
		for (PcapIf device : alldevs) {
			String description = (device.getDescription() != null) ? device
					.getDescription() : "No description available";
			System.out.printf("#%d: %s [%s]\n", i++, device.getName(),
					description);
		}

		PcapIf device = alldevs.get(0); // Get first device in list
		System.out.printf("\nChoosing '%s' on your behalf:\n",
				(device.getDescription() != null) ? device.getDescription()
						: device.getName());

		int snaplen = 64 * 1024; // Capture all packets, no trucation
		int flags = Pcap.MODE_PROMISCUOUS; // capture all packets
		int timeout = 10 * 1000; // 10 seconds in millis
		Pcap pcap = Pcap.openLive(device.getName(), snaplen, flags, timeout, errbuf);

		if (pcap == null) {
			System.err.printf("Error while opening device for capture: "
					+ errbuf.toString());
			return;
		}

		PcapPacketHandler<String> jpacketHandler = new PcapPacketHandler<String>() {

			public void nextPacket(PcapPacket packet, String user) {

				byte[] data = packet.getByteArray(0, packet.size()); // the package data
				byte[] sIP = new byte[4];
				byte[] dIP = new byte[4];

				Ip4 ip = new Ip4();
				if (packet.hasHeader(ip) == false) {
					return; // Not IP packet
				}

				ip.source(sIP);
				ip.destination(dIP);

				/* Use jNetPcap format utilities */
				String sourceIP = org.jnetpcap.packet.format.FormatUtils.ip(sIP);
				String destinationIP = org.jnetpcap.packet.format.FormatUtils.ip(dIP);

				System.out.println("srcIP=" + sourceIP + 
						" dstIP=" + destinationIP + 
						" caplen=" + packet.getCaptureHeader().caplen());
			}
		};

		// capture first 10 packages
		pcap.loop(10, jpacketHandler, "jNetPcap");

		pcap.close();
	}

}

```

如果要捕获特定的数据包，可以设置一个过滤器，如下所示：

```java
PcapBpfProgram filter = new PcapBpfProgram();
String expression = "tcp port 3724 or tcp port 1119";
int optimize = 0; // 0 = false
int netmask = 0xFFFFFF00; // 255.255.255.0

if (pcap.compile(filter, expression, optimize, netmask) != Pcap.OK) {
	System.err.println(pcap.getErr());
	return;
}

if (pcap.setFilter(filter) != Pcap.OK) {
	System.err.println(pcap.getErr());
	return;
}
```