java 套接字缓冲区大小动态
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7580958/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Socket buffer size dynamic
提问by FinalSpirit
I develop a speed test software with a graph. Each seconds, i draw the throughput on the graph. I use socket with a loop on socket.read(...)
我用图表开发了一个速度测试软件。每一秒,我都会在图表上绘制吞吐量。我在 socket.read(...) 上使用带有循环的套接字
The problem is the buffer size. If i set the buffer to 32ko, when the speed is low, my graph is wrong (block on read function until the buffer isn't full). If i set the buffer to 512 octets, the speed is "flanged".
问题是缓冲区大小。如果我将缓冲区设置为 32ko,当速度较低时,我的图形是错误的(阻止读取功能,直到缓冲区未满)。如果我将缓冲区设置为 512 个八位字节,则速度为“法兰”。
How to set dynamically the buffer size ?
如何动态设置缓冲区大小?
采纳答案by claymore1977
You can resize recv (and send) buffers like so:
您可以像这样调整接收(和发送)缓冲区的大小:
int oldsize = sock.getReceiveBufferSize();
sock.setReceiveBufferSize(oldsize * 2);
..although its not a great idea. Resizing the buffer 'on the fly' like this causes at least one massive array to array data copy to happen internal to the socket, which is a massive performance loss. Additionally, sockets have an OS restriction on their max buffer size.
..虽然这不是一个好主意。像这样“即时”调整缓冲区大小会导致至少一个大规模数组到数组数据复制发生在套接字内部,这是一种巨大的性能损失。此外,套接字对其最大缓冲区大小有操作系统限制。
If you are blocking on a read() call, then I guess you are using regular IO, not NIO. I recommend using a preallocated, fixed size intermediate buffer and loop for moving data off the socket:
如果您阻塞了 read() 调用,那么我猜您使用的是常规 IO,而不是 NIO。我建议使用预先分配的、固定大小的中间缓冲区和循环来将数据移出套接字:
/* Init socket here... */
Socket sock = new Socket(...);
/* Set time out to next to nothing. */
sock.setSoTimeout(1);
/* Setup Streams */
InputStream is = sock.getInputStream();
/* Pick a buffer size, any reasonable size will do: 1k,2k,4k... */
byte[] buf = new byte[1024 * 2];
int lastRead = 0;
do {
try {
lastRead = 0;
lastRead = is.read(buf);
} catch (SocketTimeoutException ste) {
/* Do something, or not. Your call! */
}
/*do something with 'buf' here */
} while (lastRead > 0);
By setting a low read timeout, e.g. 1ms, your read() call will not block (for very long) and you will still be able to detect whether there is data available or not. Since this potentially uses an Exception process a 'normal' condition, this really borders on abuse of java.io.
通过设置较低的读取超时,例如 1ms,您的 read() 调用将不会阻塞(很长时间)并且您仍然能够检测是否有可用数据。由于这可能会使用异常处理“正常”条件,因此这实际上接近于对 java.io 的滥用。
回答by user207421
block on read function until the buffer isn't full
阻塞读取函数直到缓冲区未满
I don't know what that means. Socket reads don't attempt to fill the buffer, they wait until some data arrives and then move that into the buffer, whatever its length, up to the size of the buffer. The size of the buffer should have no effect when speeds are low. It will take effect when speeds are high.
我不知道那是什么意思。套接字读取不会尝试填充缓冲区,它们会等到一些数据到达,然后将其移入缓冲区,无论其长度如何,直到缓冲区的大小。当速度较低时,缓冲区的大小应该没有影响。速度高时生效。
回答by NPE
One possibility is to pick a smallish buffer size, and Kalman filterthe observations before plotting them.
一种可能性是选择一个较小的缓冲区大小,并在绘制之前卡尔曼过滤观察结果。
The filter is very easy to implement, but requires calibration. For this application, I'd tune the parameters by hand until the level of smoothness of the resulting graph is pleasing to the eye.
滤波器很容易实现,但需要校准。对于这个应用程序,我会手动调整参数,直到生成的图形的平滑程度令人赏心悦目。