套接字缓冲区大小动态

时间:2011-09-28 09:18:51

标签: java network-programming

我开发了一个带图表的速度测试软件。每秒,我在图表上绘制吞吐量。我在socket.read(...)

上使用带套接字的套接字

问题是缓冲区大小。如果我将缓冲区设置为32ko,当速度较低时,我的图形是错误的(阻止读取功能,直到缓冲区未满)。如果我将缓冲区设置为512个八位字节,则速度为“法兰”。

如何动态设置缓冲区大小?

3 个答案:

答案 0 :(得分:4)

  

阻止读取功能,直到缓冲区未满

我不知道这意味着什么。套接字读取不会尝试填充缓冲区,它们会等到某些数据到达,然后将其移动到缓冲区,无论其长度如何,都达到缓冲区的大小。当速度很低时,缓冲区的大小应该没有效果。当速度高时它将生效。

答案 1 :(得分:1)

您可以像这样重新调整recv(和发送)缓冲区:

    int oldsize = sock.getReceiveBufferSize();
    sock.setReceiveBufferSize(oldsize * 2);

..虽然它不是一个好主意。像这样大小调整缓冲区大小会导致至少一个大规模阵列将阵列数据复制发生在套接字内部,这是一个巨大的性能损失。此外,套接字对其最大缓冲区大小有操作系统限制。

如果你在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);

通过设置低读取超时,例如1ms,你的read()调用不会阻塞(很长时间),你仍然可以检测是否有数据可用。由于这可能会使Exception进程成为“正常”状态,因此这实际上与滥用java.io相关。

答案 2 :(得分:0)

一种可能性是在绘制它们之前选择一个小的缓冲区大小和Kalman filter观察结果。

过滤器非常易于实施,但需要校准。对于这个应用程序,我会手动调整参数,直到结果图的平滑度令人赏心悦目。