使用pkts库读取pcap报文payload时Buffer调用toString返回乱码如何解决
解决pkts库读取pcap payload乱码问题
乱码原因
Buffer类默认toString()方法未指定编码,直接使用JVM默认编码转换字节流,和payload实际编码不匹配就会产生乱码- 抓取的报文payload本身就是二进制格式(加密流量、音视频、压缩文件等),本身无法直接转换为可读文本
- TCP协议是流式传输,单个TCP报文的payload可能只是应用层数据的分片,未做流重组直接读取也会出现乱码
正确实现方案
import io.pkts.PacketHandler; import io.pkts.buffer.Buffer; import io.pkts.packet.Packet; import io.pkts.packet.TCPPacket; import io.pkts.packet.UDPPacket; import io.pkts.protocol.Protocol; import java.io.IOException; import java.nio.charset.StandardCharsets; public class Main { // 字节数组转十六进制字符串工具方法,用于查看二进制payload public static String bytesToHex(byte[] bytes) { StringBuilder sb = new StringBuilder(); for (byte b : bytes) { sb.append(String.format("%02X ", b)); } return sb.toString(); } public static void main(String[] args) throws IOException { String t2 = "C:/Users/xxx/AppData/Local/Temp/3/xxx/dumpcap.pcap"; final io.pkts.Pcap pcap = io.pkts.Pcap.openStream(t2); pcap.loop(new PacketHandler() { @Override public boolean nextPacket(Packet packet) throws IOException { if (packet.hasProtocol(Protocol.TCP)) { TCPPacket tcpPacket = (TCPPacket) packet.getPacket(Protocol.TCP); Buffer buffer = tcpPacket.getPayload(); if (buffer != null) { // 读取准确长度的payload字节数组 byte[] payloadBytes = new byte[buffer.capacity()]; buffer.getBytes(0, payloadBytes); // 方法1:指定UTF-8编码转字符串,适配明文文本类payload String payloadStr = new String(payloadBytes, StandardCharsets.UTF_8); System.out.println("TCP明文 payload: " + payloadStr); // 方法2:转十六进制输出,适配所有类型payload调试 String hexPayload = bytesToHex(payloadBytes); System.out.println("TCP十六进制 payload: " + hexPayload); } } else if (packet.hasProtocol(Protocol.UDP)) { UDPPacket udpPacket = (UDPPacket) packet.getPacket(Protocol.UDP); Buffer buffer = udpPacket.getPayload(); if (buffer != null) { byte[] payloadBytes = new byte[buffer.capacity()]; buffer.getBytes(0, payloadBytes); // UDP同理,根据实际payload类型选择转换方式 String payloadStr = new String(payloadBytes, StandardCharsets.UTF_8); System.out.println("UDP明文 payload: " + payloadStr); System.out.println("UDP十六进制 payload: " + bytesToHex(payloadBytes)); } } return true; } }); } }
补充说明
- 处理TCP明文协议(如HTTP、FTP)时,需要额外实现TCP流重组逻辑,将同一个TCP连接的多个报文payload拼接后再转换,才能得到完整的可读内容
- 如果payload编码不是UTF-8,可以替换
StandardCharsets.UTF_8为对应编码(如GBK、ISO_8859_1) - 加密、压缩类二进制payload无法直接转换为可读文本,需要先做解密、解压缩处理
内容的提问来源于stack exchange,提问作者fauzt
相关产品推荐
相关产品推荐

