我在玩小的so-sndbuf值,主要是测试我自己的缓冲代码。
我把它设为1024(不过当我读回来时是4608)。我使用边缘触发的epoll在可以写入时得到通知。下面是我的“刷新缓冲区”函数。

    int sent = 0;
send:;
    int n = write(sock, outBuf+sent, outLength-sent);
    if (n == -1) {
        if (likely(errno == EAGAIN || errno == EWOULDBLOCK)) {
            c->writable = false;
            return;
        }
        c->valid = false;
        return;
    }
    sent += n;
    if (n && outLength-sent)
        goto send;
    c->writable = sent == outLength;
    return;

对于较大的缓冲区,这似乎可以正确执行。然而,当so_sndbuf为4608时,它会很快阻塞,然后在大约0.04秒内无法写入。
同时系统99%空闲。
0.04秒的延迟是从哪里来的?我在内核中找到了一个grep,我能找到的只有tcp_delack_min和tcp_a to_min(都设置为hz/25),尽管我不认为它们是原因?
我的密码正确吗?我是否需要goto,在man 7 epoll上给出答案9?
如果有区别的话,我使用的是tcp_nodelay,客户机和服务器在同一台机器上。

最佳答案

这是因为缓冲区已满,尚未写入网络,并且尚未被对等方确认。

关于c - 当SO_SNDBUF很小时,阻塞0.04秒,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21412872/

10-11 22:10