强制 TCP 套接字在 Java 中刷新 [英] Forcing a TCP socket to flush in Java

查看:22
本文介绍了强制 TCP 套接字在 Java 中刷新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm developing a protocol that requires a handshake that consists of several pieces of information going back and forth in each direction, with several pieces dependent on the previous pieces (think like SSL/TLS handshake). I'm trying to implement it in Java.

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

A lot of my packets are only 20-30 bytes, whereas my computer seems to think it needs to buffer hundreds of bytes before it sends anything; even if I wait 5-10 seconds (with Thread.sleep), it still won't actually send it until I close the socket.

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

How can I get Java/my computer to send what's in its buffer?

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

On other forums (and SO), a lot of people have been using arguments like "that's not how TCP works", "you shouldn't actually need that." If I need to send 10 packets each way, each one depends on the last, each one waits for 300ms in the TCP stack, I'm looking at 6s for my handshake, which is completely unusable. (Mind you, I can't get it to send at all, no matter how much I call flush on the socket; I can't get it sent at all until I close the socket).

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

I have considered just sending a packet plus enough useless padding to force the TCP implementation to force it, that seems like a bad solution.

(简化、提取)代码:

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;他们没有帮助.]

[I've tried with PrintWriter, OutputStreamWriter; they don't help.]

推荐答案

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

Try this create a simple server :

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);
}

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

Run your client code, but measure the time:

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 可能会产生影响,但对我来说它并不明显.

When I did this I got an output of 15 milliseconds. This is round trip including both read and write. If you run this and get something dramatically different, then you probably need to fix something in your network configuration. If this gives you about 15 milliseconds you need to look at the difference between this code and your code.The setTcpNoDelay might have an effect but for for me it wasn't noticeable.

这篇关于强制 TCP 套接字在 Java 中刷新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆