V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
lewis89
V2EX  ›  程序员

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

  •  
  •   lewis89 · 2020-12-26 08:05:30 +08:00 · 2572 次点击
    这是一个创建于 1419 天前的主题,其中的信息可能已经有所发展或是发生改变。
    第 2 条附言  ·  2020-12-26 08:53:10 +08:00
    已解决
    11 条回复    2020-12-26 09:52:52 +08:00
    lewis89
        1
    lewis89  
    OP
       2020-12-26 08:08:36 +08:00
    网络传输 MTU 最大是 1500 扣除以太网 TCP IP 报文头,如果我 read 一个已经握手好的 TCP 的 fd 并设置 buffer 是 4096,操作系统是尽量快速返回还是尽量塞满我的 buffer 之后再返回?
    fff333
        2
    fff333  
       2020-12-26 08:49:37 +08:00 via Android
    塞满
    zhs227
        3
    zhs227  
       2020-12-26 08:50:18 +08:00
    有个 NAGLE 算法,发包时会稍微等一下,凑齐一个大包。可以使用 sockopt TCP_NODELAY 来关掉。读的时候应该不会等,缓冲区里有多少就读多少,除非还没有收到,或者是头部阻塞了在等重传。

    想要塞满 buffer 可以多读几次,直到大于一个 buffer 以后,把多余的那一点缓存起来,放到下一轮读取里。
    lewis89
        4
    lewis89  
    OP
       2020-12-26 08:52:32 +08:00
    @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
       2020-12-26 08:54:05 +08:00
    @zhs227 #3 主要是多读几次 会不会造成 频繁上下文切换开销大的情况
    lewis89
        6
    lewis89  
    OP
       2020-12-26 08:55:39 +08:00
    @zhs227 #3 好吧 我误解了,既然发送方有 nagle 那么 read 方 自然不会被拆
    lewis89
        7
    lewis89  
    OP
       2020-12-26 09:04:34 +08:00
    @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
       2020-12-26 09:05:15 +08:00
    @zhs227 #3 这又是什么说法,启用 NODELAY,可以减少系统调用
    carlclone
        9
    carlclone  
       2020-12-26 09:14:04 +08:00
    意思是你自己在 user space 做缓存,而不是发给内核,内核帮你做缓存
    carlclone
        10
    carlclone  
       2020-12-26 09:15:15 +08:00
    缓冲..打错了
    zhs227
        11
    zhs227  
       2020-12-26 09:52:52 +08:00   ❤️ 1
    nagle 算法最主要的是如果你发送连续的小包,他会等一个计时器的长度,如果计时器的长度里有可以拼到一起的数据,就会拼在一起发送。这样会以延迟换取网络上发送的包数。但对于某些时间敏感的内容,比如 ssh,telnet,Nagle 算法并不合适。

    上面说可以减少系统调用的应该是让应用自己凑到一定长度再发。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5710 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 03:24 · PVG 11:24 · LAX 19:24 · JFK 22:24
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.