使用java计算TCP往返时间

发布于 2024-11-19 06:27:12 字数 1017 浏览 3 评论 0原文

当我使用 10 gig 网络接口从一台 Solaris m/c 到另一台 Solaris m/c 进行跟踪路由时,40 字节数据包需要 0.073 毫秒。

当我用java做同样的事情时,时间要长得多。即使经过 10K 次迭代,它仍然更长。可能是什么原因?

Java: Sender (Snippet)

Socket sendingSocket = new Socket(address, RECEIVER_PORT);
 sendingSocket.setTcpNoDelay(true);
 OutputStream outputStream = sendingSocket.getOutputStream();
 byte[] msg = new byte[64]; // assume that it is populated. 
 for (int i = 0; i < 10000; i++) {
    long start = System.nanoTime();
    outputStream.write(msg,0,64);
    outputStream.flush();

    inputStream.read(msg,0,64);  // inputStream is initialized like outputstream 
    long end = System.nanoTime(); 
 }  

需要更长的时间 69 毫秒,而且它甚至不依赖于字节大小。即使我将其减少为 1 字节数组,它仍然需要 69 毫秒。有什么意见/建议吗?

其他观察: 1.OutputStream.write和flush只需要6微秒。 2. 同样在另一端TCPReceiver端接收并写回,只需要6微秒。

解决方案: 感谢大家对此问题的回复。 我发现这是由于套接字缓冲区大小:

solaris m/c 上设置的默认缓冲区大小所致。

接收缓冲区大小49152。

发送缓冲区大小7552。

我增加了套接字缓冲区大小,性能几乎与traceRoute匹配。

When i do traceroute from one solaris m/c to another using 10 gig network interface it takes 0.073 ms for 40 bytes packets.

When i do the same thing in java, the time is way longer. It is longer even after 10K iteration. What could be the reason ?

Java: Sender (Snippet)

Socket sendingSocket = new Socket(address, RECEIVER_PORT);
 sendingSocket.setTcpNoDelay(true);
 OutputStream outputStream = sendingSocket.getOutputStream();
 byte[] msg = new byte[64]; // assume that it is populated. 
 for (int i = 0; i < 10000; i++) {
    long start = System.nanoTime();
    outputStream.write(msg,0,64);
    outputStream.flush();

    inputStream.read(msg,0,64);  // inputStream is initialized like outputstream 
    long end = System.nanoTime(); 
 }  

It takes way longer 69 millis and it does not even depends upon the byte size. Even if i reduce it to say 1 byte array, it still takes 69 millis. Any comment/Suggestion ?

Other Observation:
1. OutputStream.write and flush only takes 6 micros.
2. Similarly on the other end TCPReceiver side which receives and writes back, it only takes 6 micros.

Solution:
Thank you all you responded for this query.
I found that it was due to the socket buffer size:

Default buffer size set on solaris m/c.

Received Buffer Size 49152.

Sending Buffer Size 7552.

I increased the socket buffer size and the performance almost matches traceRoute.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

只想待在家 2024-11-26 06:27:12

你不是在比较同类。 ICMP 和 TCP 是完全不同的协议。

如果您想确定延迟是否存在于您的代码、JVM、Solaris TCP 堆栈或网络中,您必须从 tcpdump/wireshark 等开始。

You are not comparing like with like. ICMP and TCP are way different protocols.

If you want to decide if the latency is in your code, the JVM, Solaris TCP stack or the network you'll have to start with tcpdump / wireshark etc.

鲜肉鲜肉永远不皱 2024-11-26 06:27:12

这可能是由于多种因素造成的。对于初学者来说,建立 TCP 通道需要时间。必须在两个端点之间发送多个数据包才能建立可靠的介质。 ICMP 消息的情况并非如此,它们只是单个数据包。事实上,因为无论数据大小如何,您都看不到传输数据所需的时间存在差异,因此您可能会假设实际传输数据所需的时间(您正在谈论非常少量的数据)与建立通道所需的时间相比,无论哪种情况(在 10gig 连接上)都可以忽略不计。此外,完全有可能存在一些与您使用 Java(一种字节码语言)而不是在硬件上本机运行的语言(例如 C 或 C++)相关的​​开销。

This is probably due to a number of factors. For starters, establishing a TCP channel takes time. There are several packets that have to be sent between both endpoints to establish the reliable medium. That's not the case with ICMP messages, they are simply single packets. In fact, because you are seeing no difference in the time it takes to transmit the data regardless of size, then you can likely assume that the amount of time required to actually transmit the data (you're talking about a very small amount of data in either case on a 10gig connection) is negligible in comparison to the time it takes to establish the channel. Also, it is entirely possible that there is some overhead associated with the fact that you're using Java (a bytecode language) rather than something like C or C++ that runs natively on the hardware.

书信已泛黄 2024-11-26 06:27:12

连接所需的时间可能约为 20 毫秒。您需要使用现有连接进行测试。

TCP 堆栈通过内核的速度非常慢。在许多机器上大约需要 50-100 us。您可以使用内核旁路驱动程序/支持来大幅减少这种情况。

The time it takes to connect can be about 20 ms. You need to test using an existing connection.

The TCP stack is quite slow going through the kernel. It takes about 50-100 us on many machines. You can reduce this sustantially using kernel bypass drivers/support.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文