我在Android上编写了一个与服务器通信的简单套接字客户端:
Socket socket = SocketChannel.open().socket();
InetSocketAddress address = new InetSocketAddress("10.0.0.3",12345);//192.168.1.8
socket.connect(address);
DataInputStream input_stream = new DataInputStream(socket.getInputStream());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte buffer[] = new byte[1024];
int bits_read;
//we keep passing the same buffer to the read function until it returns -1 (EOF)
while((bits_read=input_stream.read(buffer))>=0)
{
baos.write(buffer, 0, bits_read);
}
byte result[] = baos.toByteArray();
String response = new String(result, "UTF-8");
当我从服务器发送带有数据的数据包时,它收到的很好,响应变量包含字符串“谢谢你连接”。但是,当我在Android上发送包含相同数据的VPN服务生成的数据包时,响应变量包含字符串“hank you for connected” - 即第一个字符(和字节)丢失。
来自服务器的数据包的hexdump是:
98 d6 f7 5e 6e 0a b8 e8 56 37 1f e6 08 00 45 00
00 4c c2 18 40 00 40 06 f5 30 c0 a8 01 08 c0 a8
01 0a 30 39 e8 c6 a8 e4 ec d8 aa 97 45 2b 80 18
20 2b 8b 87 00 00 01 01 08 0a 2e 66 a0 ea 00 61
d7 2c 54 68 61 6e 6b 20 79 6f 75 20 66 6f 72 20
63 6f 6e 6e 65 63 74 69 6e 67
来自VPN的数据包的hexdump是(以太网和帧头实际上并不是通过VPN发送的,但是我已将它们包含在这里以允许将其导入Wireshark和其他工具进行分析):
00 00 DE AD 00 00 00 00 ED EE 00 00 08 00 45 00
00 40 25 B4 40 00 40 06 01 00 0A 00 00 03 0A 00
00 02 30 39 87 D2 14 04 0F 2C 3B AB 24 08 50 18
FF FF 5E 98 00 00 54 68 61 6E 6B 20 79 6F 75 20
66 6F 72 20 63 6F 6E 6E 65 63 74 69 6E 67
两者似乎都是有效的(使用http://sadjad.me/phd/),唯一不同的是IP&源和&以外的TCP层确认号是后者没有任何TCP选项(时间戳)。但是,这怎么会导致客户端的套接字无法读取TCP数据有效负载的第一个字节?