• 请不要在回答技术问题时复制粘贴 AI 生成的内容
lewis89
V2EX  ›  程序员

网络传输 MTU 最大是 1500 扣除以太网 TCP IP 报文头,如果我 read 一个已经握手好的 TCP 的 fd 并设置 buffer 是 4096,操作系统是尽量快速返回还是尽量塞满我的 buffer 之后再返回?

  •  
  •   lewis89 · Dec 26, 2020 · 3063 views
    This topic created in 1979 days ago, the information mentioned may be changed or developed.
    Supplement 2  ·  Dec 26, 2020
    已解决
    11 replies    2020-12-26 09:52:52 +08:00
    lewis89
        1
    lewis89  
    OP
       Dec 26, 2020
    网络传输 MTU 最大是 1500 扣除以太网 TCP IP 报文头,如果我 read 一个已经握手好的 TCP 的 fd 并设置 buffer 是 4096,操作系统是尽量快速返回还是尽量塞满我的 buffer 之后再返回?
    fff333
        2
    fff333  
       Dec 26, 2020 via Android
    塞满
    zhs227
        3
    zhs227  
       Dec 26, 2020
    有个 NAGLE 算法,发包时会稍微等一下,凑齐一个大包。可以使用 sockopt TCP_NODELAY 来关掉。读的时候应该不会等,缓冲区里有多少就读多少,除非还没有收到,或者是头部阻塞了在等重传。

    想要塞满 buffer 可以多读几次,直到大于一个 buffer 以后,把多余的那一点缓存起来,放到下一轮读取里。
    lewis89
        4
    lewis89  
    OP
       Dec 26, 2020
    @zhs227 #3 老哥真及时,我刚在 StackOverflow 上 看到

    Each send call is a kernel call. But kernel calls do not correspond to individual packets, unless you've disabled packet coalescing. I suggest you read about the Nagle algorithm.

    https://stackoverflow.com/questions/28785437/tcp-sockets-send-buffer-size-efficiency
    lewis89
        5
    lewis89  
    OP
       Dec 26, 2020
    @zhs227 #3 主要是多读几次 会不会造成 频繁上下文切换开销大的情况
    lewis89
        6
    lewis89  
    OP
       Dec 26, 2020
    @zhs227 #3 好吧 我误解了,既然发送方有 nagle 那么 read 方 自然不会被拆
    lewis89
        7
    lewis89  
    OP
       Dec 26, 2020
    @zhs227 #3 Indeed, the wikipedia article strongly recommends you buffer writes yourself and disable Nagle. Reduced cost of kernel calls is another benefit.
    lewis89
        8
    lewis89  
    OP
       Dec 26, 2020
    @zhs227 #3 这又是什么说法,启用 NODELAY,可以减少系统调用
    carlclone
        9
    carlclone  
       Dec 26, 2020
    意思是你自己在 user space 做缓存,而不是发给内核,内核帮你做缓存
    carlclone
        10
    carlclone  
       Dec 26, 2020
    缓冲..打错了
    zhs227
        11
    zhs227  
       Dec 26, 2020   ❤️ 1
    nagle 算法最主要的是如果你发送连续的小包,他会等一个计时器的长度,如果计时器的长度里有可以拼到一起的数据,就会拼在一起发送。这样会以延迟换取网络上发送的包数。但对于某些时间敏感的内容,比如 ssh,telnet,Nagle 算法并不合适。

    上面说可以减少系统调用的应该是让应用自己凑到一定长度再发。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   5341 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 466ea39e · 53ms · UTC 07:04 · PVG 15:04 · LAX 00:04 · JFK 03:04
    ♥ Do have faith in what you're doing.