gpt4 book ai didi

java - 强制 TCP 套接字在 Java 中刷新

转载 作者:可可西里 更新时间:2023-11-01 02:31:45 26 4
gpt4 key购买 nike

我正在开发一个需要握手的协议(protocol),该握手包含在每个方向上来回传递的几条信息,其中几条信息依赖于之前的信息(类似于 SSL/TLS 握手)。我正在尝试用 Java 实现它。

我的很多数据包只有 20-30 个字节,而我的计算机似乎认为它需要在发送任何内容之前缓冲数百个字节;即使我等待 5-10 秒(使用 Thread.sleep),在我关闭套接字之前它仍然不会真正发送它。

如何让 Java/我的计算机发送其缓冲区中的内容?

在其他论坛(和 SO)上,很多人一直在使用诸如“这不是 TCP 的工作方式”、“你实际上不应该需要它”之类的论点。如果我需要每路发送 10 个数据包,每个都依赖于最后一个,每个都在 TCP 堆栈中等待 300 毫秒,我正在寻找 6 秒的握手时间,这是完全无法使用的。 (请注意,无论我在套接字上调用多少次 flush,我都根本无法发送它;在关闭套接字之前,我根本无法发送它)。

我考虑过只发送一个数据包加上足够多的无用填充来强制 TCP 实现强制它,这似乎是一个糟糕的解决方案。

(简化、提取)代码:

Socket sock = new Socket("localhost", 1234);
OutputStream output = sock.getOutputStream();
output.write(new byte[] {(byte) 0xde, (byte) 0xad, (byte) 0xbe, (byte) 0xef});
output.flush();
Thread.sleep(5000);

[我尝试过使用 PrintWriter、OutputStreamWriter;他们没有帮助。]

最佳答案

尝试创建一个简单的服务器:

public static void main(String[] args) throws IOException {
ServerSocket svr = new ServerSocket(1234);
Socket s = svr.accept();
byte b4[] = new byte[4];
new DataInputStream(s.getInputStream()).readFully(b4);
s.getOutputStream().write(b4);
}

运行您的客户端代码,但测量时间:

public static void main(String[] args) throws IOException {
Socket sock = new Socket("localhost", 1234);
OutputStream output = sock.getOutputStream();
long t1 = System.currentTimeMillis();
output.write(new byte[]{(byte) 0xde, (byte) 0xad, (byte) 0xbe, (byte) 0xef});
byte b4[] = new byte[4];
new DataInputStream(sock.getInputStream()).readFully(b4);
long t2 = System.currentTimeMillis();
System.out.println("t2-t1="+(t2-t1));
}

当我这样做时,我得到了 15 毫秒的输出。这是往返,包括读取和写入。如果你运行它并得到一些截然不同的东西,那么你可能需要在你的网络配置中修复一些东西。如果这给您大约 15 毫秒,您需要查看此代码与您的代码之间的区别。setTcpNoDelay 可能会产生影响,但对我来说并不明显。

关于java - 强制 TCP 套接字在 Java 中刷新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32445734/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com