套接字:BufferedOutputStream还是只是OutputStream?

时间:2012-07-07 07:46:47

标签: java sockets tcp bufferedinputstream bufferedoutputstream

为了在Java中获得最快的TCP传输速度,这是更好的:

选项A:

InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();

选项B:

BufferedInputStream in = new BufferedInputStream(socket.getInputStream());
BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream());

我已经读过,当将8 KiB写入OutputStream时,性能会受到影响,建议它一次性写入小块,而不是写入8 KiB。 8 KiB是BufferedOutputStream的默认缓冲区大小。

但是我还读到,当通过网络传输数据时,尽可能快地清除字节是很好的。这意味着使用缓冲区并以小块写入会增加不必要的开销。

那么,选项A还是选项B?哪个效果最好?

现在我猜测选项A提供了最高的传输速度,同时消耗了比选项B更多的CPU。选项B可能更好,因为它没有那么慢,但节省了大量的CPU。

-

奖金问题:触摸TCP窗口大小是个好主意吗?例如,将其设置为64 KiB:

socket.setReceiveBufferSize(65536);
socket.setSendBufferSize(65536);

我尝试在测试机器上将其设置为128 KiB,因为我读到它可以提高速度但是当服务器有几个连接时,CPU是100%而不是2%,就像我单独离开时一样。我猜128 KiB太高了,除非你有一台能够处理流量急流的好服务器,但将它设置为32 KiB是否明智?我认为我的默认值是8 KiB。

(“socket”是“java.net.Socket”)

2 个答案:

答案 0 :(得分:8)

我不知道你在哪里阅读所有废话,但它完全回到了前面。你一次写入TCP连接的次数越多越好,同时你读取的次数也越多。我总是在应用程序和套接字流之间使用缓冲的流,读取器或编写器。在某些情况下,例如SSL,一次直接写入一个字节会导致40倍的数据爆炸。

  

触摸TCP窗口大小是个好主意吗?例如,将其设置为64 KiB

您无法'触摸TCP窗口大小'。你可以通过你提到的API来增加它的最大价值,这确实是一个好主意。

答案 1 :(得分:-1)

速度是什么意思?低延迟或高吞吐量?

对于低延迟,请在完成写入后立即刷新流。

对于高吞吐量,请使用缓冲流并让VM / OS处理其刷新。