Android VpnService读取数据乱码,无法获取HTTP请求内容求助
解决Android VPN读取网络数据转字符串乱码的建议
先剥离IP/TCP协议头,再处理HTTP payload
你通过ParcelFileDescriptor读取的是完整的底层IP数据包,包含IP头、TCP/UDP头,直接把整个字节数组转字符串必然乱码。需要先拆解协议头:- IPv4头长度:取字节数组第0位的低4位,乘以4(无选项的IPv4头固定20字节)
- TCP头长度:取IP头后第12位的高4位,乘以4
跳过这两部分后,剩下的字节才是真正的HTTP请求内容,再尝试转字符串。
处理TCP分包拼接
HTTP请求可能被拆分成多个TCP包发送,单次读取的字节数组可能只是请求片段。需要维护每个TCP连接的上下文,把同一个源/目的IP+端口的分包数据拼接完整后,再解析HTTP请求行和头部。用十六进制输出验证字节内容
把读取到的字节数组转成十六进制字符串打印,对比标准HTTP请求的十六进制值(比如GET对应47 45 54 20),确认是否能在字节流中找到这些标识,以此判断是协议头未处理还是编码问题。编码匹配验证
确保解码用的编码和HTTP请求实际编码一致,大部分场景用UTF-8,但部分旧系统可能用ISO-8859-1或GBK。但前提是你已经拿到了正确的HTTP payload部分。协议头拆解示例代码
// 假设读取到的原始字节数组为buffer if (buffer.length < 20) return; // 至少要包含IPv4头 // 计算IPv4头长度 int ipHeaderLen = ((buffer[0] & 0x0F) * 4); // 计算TCP头长度(IP头之后的第12字节是TCP头的data offset字段) int tcpHeaderLen = ((buffer[ipHeaderLen + 12] & 0xF0) >> 4) * 4; int payloadStart = ipHeaderLen + tcpHeaderLen; if (payloadStart < buffer.length) { byte[] httpPayload = Arrays.copyOfRange(buffer, payloadStart, buffer.length); String httpContent = new String(httpPayload, StandardCharsets.UTF_8); // 此时再处理httpContent即可 }
内容的提问来源于stack exchange,提问作者mohammad javad haji
相关产品推荐
相关产品推荐

