套接字:BufferedOutputStream还是只是OutputStream?

为了在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”)

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

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

你不能’触摸TCP窗口大小’。 您可以通过您提到的API增加其最大值,这确实是一个好主意。

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

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

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