某些东西正在改变写入我的 Windows (Windows 7) 机器上的 TCP 套接字的数据 - 具体来说,当字节遵循特定的 HTTP POST 模式时,当从连接的相应侦听器套接字端读取字节时,模式会重复。
以下字节被写入客户端套接字(注意:每行以回车符和换行符结尾,两个非空行后跟两个空行):
POST / HTTP/1.1
Transfer-Encoding: chunked
从侦听器套接字读取的内容是:
POST / HTTP/1.1
Transfer-Encoding: chunked
POST / HTTP/1.1
Transfer-Encoding: chunked
我已经在我的机器上的环回(127.0.0.1)地址上对此进行了测试,但是当侦听器套接字在另一台机器上时,我也看到了修改后的字节,所以看起来字节在客户端被修改了。我已经在我的机器上使用 netcat 和 java 程序(见下文)重现了这个问题,所以问题似乎出在 TCP 堆栈中。我只能使用一组特定的 HTTP 标头来触发它,因此似乎有什么东西正在对我的 TCP 通信进行深度数据包检查并对其进行更改。如果我稍微改变输入字节(例如,它不是一个有效的 HTTP 请求,例如,将“POST”更改为“QOST”,它工作正常)。
下面是我编写的一个 java 程序,它演示了这一点及其输出:
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.Charset;
public final class Main {
private static final String PAYLOAD
= "POST / HTTP/1.1\r\n"
+ "Transfer-Encoding: chunked\r\n"
+ "\r\n"
+ "\r\n"
;
private static final int PORT = 8080;
public static final void main(final String[] args) throws Exception {
final Thread serverThread = new Thread(new Server());
serverThread.start();
final byte[] payloadBytes = PAYLOAD.getBytes(Charset.forName("UTF-8"));
int i = 0;
try (final Socket socket = new Socket(InetAddress.getLoopbackAddress(), PORT)) {
socket.setTcpNoDelay(true);
final OutputStream os = socket.getOutputStream();
for (final byte byteValue : payloadBytes) {
os.write(byteValue);
os.flush();
i++;
}
}
serverThread.join();
System.out.println("bytes written: " + i);
}
private static final class Server implements Runnable {
@Override
public void run() {
try (final ServerSocket serverSocket = new ServerSocket(PORT)) {
// while (true) {
final Socket socket = serverSocket.accept();
socket.setTcpNoDelay(true);
try (final InputStream is = socket.getInputStream()) {
int i = 0;
int byteValue;
while ((byteValue = is.read()) >= 0) {
System.out.print((char) byteValue);
System.out.flush();
i++;
}
System.out.println("----------------");
System.out.println("bytes read: " + i);
}
// }
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
}
}
输出:
POST / HTTP/1.1
Transfer-Encoding: chunked
POST / HTTP/1.1
Transfer-Encoding: chunked
----------------
bytes read: 96
bytes written: 49
下面是在 windows 上使用 netcat(来自 cygwin 的 nc.exe)的相同测试(注意:文件 test_payload.blob 包含如上所述的字节,并从 java 程序中的 PAYLOAD 常量派生):
启动 nc 监听器:
nc -l 8080 > nc_capture; more nc_capture
运行 nc 客户端(在侦听器的另一个 shell 中):
nc -v 127.0.0.1 8080 < test_payload.blob
写入 nc_capture 的输出:
POST / HTTP/1.1
Transfer-Encoding: chunked
POST / HTTP/1.1
Transfer-Encoding: chunked
我的第一个想法是防火墙有问题,所以我禁用了它,但它仍然会发生。我也试过重置我的winsock和tcp/ip,它仍然发生。我尝试禁用我的所有网络适配器(上述测试适用于环回 IP 地址,因此不需要它们),它仍然会发生。在这一点上,我几乎没有想法,我什至不知道我将如何尝试在较低级别进行调试。有没有人见过这样的东西?Windows 上是否有一些低级别的诊断工具,我可以使用它来查看它可能与我的 TCP 堆栈挂钩的内容?