Java SOCKS 地址中的负数并不等于负 IP
用 Java 的 byte API 解析 SOCKS 地址字段时,应按无符号协议值读取。
Java 的 byte 是有符号的。因此,当线路上取值为 217 的字节直接从 byte 数组打印出来时,可能显示为负数。这并不意味着代理发送了无效的负 IP 地址。
应把存储的取值转换为无符号整数,例如使用 Byte.toUnsignedInt(value),或在读取字段时改用 DataInputStream.readUnsignedByte()。对于网络字节序的端口,应读取文档规定的两字节值,而不是把其中任一字节当作有符号十进制数。
还要把表示方式与分帧区分开。一次 socket 读取可能返回的字节少于请求的数量。应先读满整个字段,再按 SOCKS 版本和地址类型进行解释。SOCKS5 地址可能包含 IPv4 地址、IPv6 地址或带长度前缀的域名;固定按四字节处理只能覆盖其中一种形式。
修正看似负数的字节只解决了显示问题。它并不能修复从错误偏移开始读取、或在地址中途停止的解析器。